{"_id":"alispig-advanced-chat","_rev":"70-aa83a35f7101dc235f1b91597040e2f0","name":"alispig-advanced-chat","dist-tags":{"latest":"1.4.3","beta":"1.5.6-bate.14"},"versions":{"1.4.2":{"name":"alispig-advanced-chat","version":"1.4.2","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"^1.2.0"},"optionalDependencies":{"lamejs":"^1.2.0"},"gitHead":"10418ff25489a21771daebd00966b6cf6c74cc22","_id":"alispig-advanced-chat@1.4.2","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-BPoKw7DZn5/BWISyrqKzqA7ya7F8DjqLEUdoN9kzWTnO9Sm/JrcDnIlvEMaidgNVA98hyQMlzTZEzri2cTPK4w==","shasum":"1b05e844975f44706a43ae6a2ff6db61f130ed42","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.4.2.tgz","fileCount":16,"unpackedSize":14727719,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhtLahCRA9TVsSAnZWagAAnUYQAI+NGJHfPc11aPQWDRnX\nNeKILBnDJ4MSAEIDYviJt91T3BeWWIQNWZv3xtwtcTku2/aTgQitbcoWHSs5\nN2pVZeK5Btun3rfiXhzcTLBIK40YuPD0Lhhr4w0doFwHNBSgdQ6+Q8rbMyeE\n+DZ1vAliBdwXBE26AY5I8btvS3zDEaer1ae3rsFKv8Jb31g2XShe2cACVMHK\nIhYBu576M9MuhbwSjEVsTJbNhKVviglTfZhKQ7ciM2fOxbgk1sqJJ8fcT5Jz\nczRYHc2CUz+sFMqAXtKOlZnLcevAs2xugnELHkEVW84/KFPwHsW0y+fwS3f4\nCsq5Ez7N+5zlYaXcs4BAGxA7fJ2ykfzoL16x2DonrwV9SRrejgTZgNQc36A5\nw/lvgKeiNvdi+kdzjf1QQMQharCnbDuXWUxp7TY0K59KmCF5BwK2FD1j5qeK\n6u3zSG/c7Kunk1G1RIgSZsseA730/r88TyXOlDJJ0SY0qedhzfFup8taLrhz\n3PZxL2oLn0gZ90U3qnaBbvblAT67VwbbpqSaY1zAj1FQDfur1cC82hYSlmQs\nsNSk1LVNwDolTbmaOWgimHMhSFoW2IgLjSrYrxl9dCuoVk/dZq7d0DqraxlQ\nt3VkFaL9u+IE+I6ggjtlptSjGnmJ8ybthrYQuloDpIw0OOjZfgdTK4cGsS9F\nL5wY\r\n=HRn0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC298sRxxEKATKVA8aB0OEy6+Ebc/ZTtRM10O9pfjxvJgIgesH4ha/4WNzEdJ3yRPu7KoVUWoWMz/uhYdud0oP8IPs="}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.4.2_1639233185166_0.020785096461437114"},"_hasShrinkwrap":false},"1.4.3":{"name":"alispig-advanced-chat","version":"1.4.3","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"^1.2.0"},"optionalDependencies":{"lamejs":"^1.2.0"},"gitHead":"dbb401da399dc828f3a6c3b23fd1f3d7e92debb0","_id":"alispig-advanced-chat@1.4.3","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-tMNS0n+1EXViLvtDR8QGXkSuzmhiW6TIBdEplEX3db+P4T9VH6/ZrITX41nLGWDS9c7KV+pNUklUBzairGo9RQ==","shasum":"4b8bb45a73717590f9a1724cb3017b22317cceab","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.4.3.tgz","fileCount":16,"unpackedSize":14747495,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhwGLyCRA9TVsSAnZWagAAIo0P/jXZfKfRDW0FCi65/eSO\nEga1g2dTK/DejEkgC2yYLyO5J6In2d+MiS5QVfMDcPZPlHacS5jj4k6JjUDw\nfpuno44yf+GwfrYDjNP7qEPS/PlrPhohXy4YLVQK8dzF6R8auA/nuIvQpOgj\nH57FShhj+GdNe9AmzNgt0BZy44QStStEgIlkn16XxH4/8Q9gxJn/QBVYigIf\nWapWs1S3rw5xtngZw622ggcwzojLQI0naUMFtek9HvAjRbtdBzo0DIqgt9zD\npDo+W3+x1F73rrDvQBMKMLbWBdDNO4ONQKVxwTgNPvERhrd42HKY36WfRqbe\ndpqEWVotZHZJU4HLOveM4P929rl4o89UhJ6VEgqVS4eBfwpQ40ZPVnDjkFah\n5fuDwyLSRQsDqGcNaGnrRAX9r8CKRgdgEpL1SbLLr73bDX35GYKwVIz2WwzE\na0iMSHrF/TvOsNM6iXZ1MHmkZTHwFpk7KFdFPazPQzoqtswKSCf+7KFc/Vo3\n00ItGzsUYNeq93kTdDsr88AXH3aOfQ3/k4c5VcgeGx3VTS40Tox6cJLYin66\nq3ObaSfJqGWP+cR4+Wm+v/758mpidB163AjlLrEK65ArXe8q7cEcN0NRQV1m\nbB7Q6MCx3nT53yB2mliyJDn5rAaxHOpweppdH+GRdgTBeRqI4dCYTrAtBHez\n+++K\r\n=XNi0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIASypqxzBpXG4IekvLaJFJZQkVmkkFpxv8v0SWcBkL0GAiEAtGaYlznRrCntkkfUi1xFphFd113Qqac6HqAxF6Fv+qY="}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.4.3_1639998194171_0.5693496511598841"},"_hasShrinkwrap":false},"1.4.4":{"name":"alispig-advanced-chat","version":"1.4.4","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"^1.2.0"},"optionalDependencies":{"lamejs":"^1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `messages-loaded`(7)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(8)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(10)               | Array            | -        | (10)                                                                                                              |\r\n| `templates-text`(11)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(12)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(13)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(14)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(15)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(16)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(17)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (18)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(19)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(20)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(21)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(22)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(23)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(24)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(25)                        | Object           | -        | (23)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(8)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(9)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(13)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(14)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(15)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...'\r\n}\"\r\n```\r\n\r\n**(16)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(17)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(18)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(19)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(20)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(21)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(22)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(23)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(24)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(25)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div> | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------ | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                  | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                       | `{ roomId, content, files(9), replyMessage(10), usersTag }`               | Sent a message                                  |\r\n| `edit-message`                       | `{ roomId, messageId, newContent, files(9), replyMessage(10) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                     | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                          | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                   | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                           | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)          | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `send-message-reaction`              | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (7)                      | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                  | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(8)         | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                     | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(8)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(10)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                   | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                              | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                              |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                              | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                   | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                   | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus` | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                              |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus` |\r\n| `room-options`                      | Replace the template of the room options                    | -                                   | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                           | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                   | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                   | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                   | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                   | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                   | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                   | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                    | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                   | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                   | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                   | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                   | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                   | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                   | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                   | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                   | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                   | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                   | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                   | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                   | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                   | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                   | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                           | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                           | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                     | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                   | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                   | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                   | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                   | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                   | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                   | -                                                                                                                  |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n#### Angular Setup\r\n\r\n```json\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"035c8a3e17770167256b923be6944975fbaaaf99","_id":"alispig-advanced-chat@1.4.4","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-RrrtXVQn088K3/r5xRwxKFTRr1ba80YFeYgviFeV6TjS6wO4lInnEpawa0ClAyWxQcyJzWsRiyCuZYkhhrIP2w==","shasum":"b58fe5299e94a9072cee87b6d9f6efd80287e541","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.4.4.tgz","fileCount":16,"unpackedSize":14766967,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhz/PhCRA9TVsSAnZWagAAuY0P/R+Oir/43yF5I5LeakvK\n9e/+6HfAoZyBsDAyhYvo7ceBN3rGD6q8n8+JoyfJQA3leIOC3/fLj9EAhljb\nYBJy0fctP4ZGRLjrVf4I+bchKXv0T7s5H1MrYuuvHwJRkEfeCodbzp/jHKgs\ndg0gWtKnODrqCcCyUC9XHLLBfh35+fSGEVfWVkOH9q66PNmFz9ChwfqT6unB\n2qrG9a4K84C8/4X0iJbiDNLASUdZ1ru8B3bc5uJfdLeWxPKlvWXkCswqr1sR\neoeP3j4eLKkBBpOM5kdymh1+v1BLf/SE7tGKLQd9nMrGWGqzOrofgaLdVgRN\nPBk5RIYtbP2gL5qigAm9lW/P8PRvRhctwlCmQcO4rOeK43VaPkaF3YUeEVRr\nESHu4GYPirL9qpFVUu6nS79MsTyAXHA6swC88aj+CoYvnOrBzf4MeX5vUtl7\ncXxcKpu9/Q3xrVX5SMqJ/q8st4oAhks/pMgwy87Pj+6SwlIGZtMgK5OYcBaP\nB36a7tlRFzH5dODxu4Ng/3V+VS2CVN49/uhiCunSOrhfG7sx51XFutxcJdKB\nJk3iUjFS9MUt5aTF8O3cM2CsSQrxlfekN2mX2iKd5MvMb9KoENvAnG9vbSuy\nyaGAz3ZzQm/wqDcvpBCY2DTAnWHzup9IqijUtaWo8aYuIl3xSBhDqv0djjDx\nQ9rz\r\n=/0Ut\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCHMNGPNVzfEqu5HRPf+QLRLcbBXegpJnbYPB71o29+PAIhAMNy+cfZ20RuS8hezh7COkAvZ3x/423Gkqoswyw4LboQ"}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.4.4_1641018337048_0.35414847144915584"},"_hasShrinkwrap":false},"1.4.5-bate.0":{"name":"alispig-advanced-chat","version":"1.4.5-bate.0","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"^1.2.0"},"optionalDependencies":{"lamejs":"^1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `messages-loaded`(7)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(8)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(10)               | Array            | -        | (10)                                                                                                              |\r\n| `templates-text`(11)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(12)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(13)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(14)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(15)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(16)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(17)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (18)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(19)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(20)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(21)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(22)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(23)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(24)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(25)                        | Object           | -        | (23)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(8)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(9)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(13)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(14)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(15)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...'\r\n}\"\r\n```\r\n\r\n**(16)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(17)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(18)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(19)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(20)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(21)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(22)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(23)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(24)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(25)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div> | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------ | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                  | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                       | `{ roomId, content, files(9), replyMessage(10), usersTag }`               | Sent a message                                  |\r\n| `edit-message`                       | `{ roomId, messageId, newContent, files(9), replyMessage(10) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                     | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                          | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                   | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                           | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)          | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `send-message-reaction`              | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (7)                      | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                  | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(8)         | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                     | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(8)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(10)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                   | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                              | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                              |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                              | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                   | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                   | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus` | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                              |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus` |\r\n| `room-options`                      | Replace the template of the room options                    | -                                   | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                           | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                   | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                   | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                   | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                   | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                   | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                   | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                    | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                   | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                   | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                   | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                   | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                   | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                   | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                   | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                   | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                   | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                   | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                   | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                   | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                   | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                   | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                           | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                           | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                     | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                   | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                   | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                   | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                   | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                   | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                   | -                                                                                                                  |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n#### Angular Setup\r\n\r\n```json\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"035c8a3e17770167256b923be6944975fbaaaf99","_id":"alispig-advanced-chat@1.4.5-bate.0","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-iyRCalf+0Se19I9Dj+X3MUHEGqvnMy+Lzy0xjYcZyPnSbuHNmHJkoZbFWOWXYocq51H+3yGo0898WdZXwWENWw==","shasum":"9b5aafa9e2ae5b183eb5ca4f20b4bc75da26ebf9","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.4.5-bate.0.tgz","fileCount":16,"unpackedSize":14771052,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh07JvCRA9TVsSAnZWagAAnwIP/is3mujbTOujQJDtmLek\ntIc65g8NZxQICwvvPAVi/aNYVvWhGDHqJdvp+Z+nfYc9Y1IEldwCM1nEemZQ\nK2szvgDaeDH5it+LQI7BWjPE3TUu3QrkFUK0EmyIaZUUOW8l71k9S6V7wahy\nzL4mCtlqngNIxq/a9rEAW0barJ2V/+woF5kUjVNX1cVikaMU27y9xBp0fehn\nVJTLlHrDGOKIzbPq0/drqDot/AgzroOE1ajiHTQ97GiN/NkLao6+jT4GpfHv\nVkjSWyNp8NlEkdHF8utfdz1pdi77JzcGcLV1gSm/knlKGuhIBG5DqhpgAHJT\nvV4Iw8sApvpL+fLxQv0bp19dfC6pB5JeHR4XplG+HLXZlXFKtdF99dYhe8X9\nfGbbdtGaPZ0YI7gNBxds6B5Shx0FwOZ8mOj9W56NM9YBqn9xi4fXXtE6E5a4\nK7nlurNaE4tya8CIMa2ZJxksloD3llgDEQEcT+On9fRCTrLzku0YEO38YbIQ\nX2Mp6QQ/AruV0JkAUSZtaOIXp9R6ShP8aq4VJtYS13WVg61TEBWIiDp7f0D4\n10sChDx2Gz1/Y1JqPls8cGXCSKtlReg2a6Zrs22HHw+wMks4JYsYD8QVSMWy\nQoP7P8NowQFkLjaaCwD/f3uklqsWH8LRWyQQBrVKN+qOwPJCikOOkhX6G8kl\nhXKH\r\n=baYn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHYdQXOG1qsMKW2qpYXsurfVkIoJhz5L3gLUIPa9MA0eAiEAtpvKIfGBtlHKz31mA5JW0ohgR21mTtfNtl4p1RDJOWo="}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.4.5-bate.0_1641263727395_0.34091557154696206"},"_hasShrinkwrap":false},"1.4.5-bate.1":{"name":"alispig-advanced-chat","version":"1.4.5-bate.1","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"^1.2.0"},"optionalDependencies":{"lamejs":"^1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `messages-loaded`(7)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(8)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(10)               | Array            | -        | (10)                                                                                                              |\r\n| `templates-text`(11)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(12)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(13)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(14)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(15)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(16)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(17)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (18)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(19)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(20)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(21)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(22)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(23)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(24)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(25)                        | Object           | -        | (23)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(8)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(9)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(13)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(14)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(15)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...'\r\n}\"\r\n```\r\n\r\n**(16)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(17)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(18)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(19)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(20)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(21)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(22)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(23)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(24)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(25)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div> | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------ | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                  | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                       | `{ roomId, content, files(9), replyMessage(10), usersTag }`               | Sent a message                                  |\r\n| `edit-message`                       | `{ roomId, messageId, newContent, files(9), replyMessage(10) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                     | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                          | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                   | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                           | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)          | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `send-message-reaction`              | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (7)                      | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                  | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(8)         | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                     | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(8)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(10)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                   | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                              | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                              |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                              | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                   | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                   | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus` | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                              |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus` |\r\n| `room-options`                      | Replace the template of the room options                    | -                                   | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                           | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                   | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                   | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                   | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                   | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                   | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                   | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                    | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                   | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                   | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                   | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                   | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                   | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                   | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                   | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                   | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                   | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                   | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                   | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                   | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                   | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                   | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                           | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                           | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                     | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                   | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                   | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                   | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                   | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                   | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                   | -                                                                                                                  |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n#### Angular Setup\r\n\r\n```json\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"035c8a3e17770167256b923be6944975fbaaaf99","_id":"alispig-advanced-chat@1.4.5-bate.1","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-SSGJ7LiXCCtbLDjVB28BLXuhXC8gKda5Y7UiH8Zu4F7tcsqoA+DeGWarFwCw8IeZEcQz5SVChtSW9J7geKq0Kg==","shasum":"1772a97822b240d6d9ef1c5e88e437edce130d7d","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.4.5-bate.1.tgz","fileCount":16,"unpackedSize":14771082,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh08t9CRA9TVsSAnZWagAAOLUP/3gw1ZnWcNoHSfAeD7zr\nBjg+G6tWZ/33BLmro+Tmz486uUNKm5EWTICcOt7Wgzb0uPnOgEVczCv+hBhC\nJx5HypGrDc3cG+4t5pis31+GSjDh+o07tjwgSkc/t7KSvf5rfJprZwvHFxxd\nWdHb36c9IkizzpQJ4Iff4+7qu8XhKZQ3RwhZFXiXOuqJDLlRfx8qA81UnL3X\niKVouyw1Yy01qvG2Y5/NEiMpM2F48wCIk+OSNI64vo4oElLAX6rr5QyIf79G\n/mdxOuXYSBhcxNKv9L0LA2QBo7HBkQ6FVmshpgtRzQ5COol+pUDPdgWiaO7p\n49/if3AcrTSEB0W6hxgV7soB3sUt6GzXykatvxaNxJzJDqjxPLZdJVGk7tjs\nx+Q7RLqToCc5QAQf8GwI4V7Tt+suXY7w32UAEtobBFYoRk6iv65vRIXfLs/w\nCtIGnu+giKhg1dtEiyCOy6d54PBbGcfR4fa2Jo+kheipmev01A14BsNZk+JP\nmbd6TRJEQPjy8ZYzirPPxsZ3NwBp9zhn13RQjo8oZ/ODvusf/Ejlzv7YaB2o\nHOouc/EV06BWJQCfFqnYxZPti4/cUcLkBBl60NDlHesENvZxiSUh8Q51nS7j\nsvcSj8nG7mR009CinMSprl833HPEuVdcu/RL4mNp0vbo257CPrzReXHnmSam\nBFbR\r\n=Bw0X\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCy1hNNXhhvMB/UFwTDvtpDpk+vkdD2/sQgRAPkBf6RRgIgLdzR4CD08rwph/pW6BokwVQJX0wZ+ScILZ5oowCY228="}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.4.5-bate.1_1641270141060_0.6357903533041314"},"_hasShrinkwrap":false},"1.4.5-bate.2":{"name":"alispig-advanced-chat","version":"1.4.5-bate.2","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"^1.2.0"},"optionalDependencies":{"lamejs":"^1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `messages-loaded`(7)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(8)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(10)               | Array            | -        | (10)                                                                                                              |\r\n| `templates-text`(11)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(12)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(13)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(14)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(15)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(16)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(17)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (18)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(19)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(20)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(21)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(22)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(23)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(24)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(25)                        | Object           | -        | (23)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(8)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(9)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(13)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(14)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(15)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...'\r\n}\"\r\n```\r\n\r\n**(16)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(17)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(18)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(19)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(20)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(21)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(22)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(23)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(24)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(25)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div> | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------ | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                  | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                       | `{ roomId, content, files(9), replyMessage(10), usersTag }`               | Sent a message                                  |\r\n| `edit-message`                       | `{ roomId, messageId, newContent, files(9), replyMessage(10) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                     | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                          | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                   | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                           | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)          | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `send-message-reaction`              | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (7)                      | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                  | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(8)         | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                     | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(8)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(10)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                   | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                              | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                              |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                              | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                   | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                   | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus` | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                              |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus` |\r\n| `room-options`                      | Replace the template of the room options                    | -                                   | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                           | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                   | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                   | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                   | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                   | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                   | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                   | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                    | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                   | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                   | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                   | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                   | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                   | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                   | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                   | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                   | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                   | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                   | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                   | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                   | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                   | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                   | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                           | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                           | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                     | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                   | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                   | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                   | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                   | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                   | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                   | -                                                                                                                  |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n#### Angular Setup\r\n\r\n```json\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"035c8a3e17770167256b923be6944975fbaaaf99","_id":"alispig-advanced-chat@1.4.5-bate.2","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-dUyOTimNQ1LkiGQAFVtNPXXMCWUXl+SUmTYf9fTbxfeOqMXpqLckvUhxqeQacDa1HANVHaHePiG39NFfHTeAFg==","shasum":"fd955ae9bc85e35bf47b7e48fb472a01ba9c5f53","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.4.5-bate.2.tgz","fileCount":16,"unpackedSize":14779182,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh0/taCRA9TVsSAnZWagAAMO0P/iDJEMWLuU4n3rCkxfTv\n+qwYTy8nAozDzP3JLr5FBOiIO1EeGUGFiD5Rm+rMIs8lM6gGbeiNwnJxtLwi\n4IFFwK2uOhCaFX5xa6s+nqX3dVcX1GLPMGHOHbtvkcGSZvWrN2jwOix7mozD\n2df4nqkVs89sUAu7hnFmGz80uQsE7v5OmvuM6Lo61gQ4puy+BKUilH2ppiCP\nhBSa3aWEgE+kUxftCQFmbotQ1M8vWvxLObMm51jvjVBohYiatZCcjZYcd02F\nzDftU0Pn0yDKlE+9YC8IVxBy6zDfhW2mWQNd4T9dbPIkA6FgfPCZi301L3hJ\n8PtSvIe9TyJZnZsjs4xtr3jhuVJmwTymcDcQiSa1wr/jKZSiEl3pQ/tqh8xa\noAL6gGcVWq+RE8krSy/mTleXCmmt1G9m4EwbU4oFHw6MiPBym8FGWWLIE/aR\nMdCFENwV7in0Iy59g+dTguBcnB7Y1WWfyyyt8FvGO6F9Z1OYnRH6JsUyeoCJ\nWfBayGiQiyWgVgBdnT352A4F07XOCUvLM5N24cZzbe62oAG/MGcOVsdbzvCI\nlLXCY0eW/VERjvk7oWjsI2yCoPECprsNhUVaA4ZvBEyrtl65s1p2GMSpbUdv\nbbSadEefjqnv5ArIXiYf7tgn83wQ5WW7fEf92Gzxd5ACRcqUGkcyDCcaVfdy\nYYSv\r\n=/UqF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAVWw5PoLjrieeudzCeeBXAX4TEkBkwJ2Q90XXUhtejQAiAbbf9MPfBqmldQ+P2Qxroz3SgZgaGQG9jd59WYBSVODg=="}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.4.5-bate.2_1641282394173_0.24863933698245022"},"_hasShrinkwrap":false},"1.4.5-bate.3":{"name":"alispig-advanced-chat","version":"1.4.5-bate.3","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"^1.2.0"},"optionalDependencies":{"lamejs":"^1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `messages-loaded`(7)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(8)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(10)               | Array            | -        | (10)                                                                                                              |\r\n| `templates-text`(11)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(12)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(13)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(14)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(15)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(16)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(17)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (18)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(19)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(20)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(21)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(22)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(23)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(24)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(25)                        | Object           | -        | (23)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(8)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(9)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(13)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(14)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(15)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...'\r\n}\"\r\n```\r\n\r\n**(16)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(17)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(18)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(19)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(20)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(21)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(22)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(23)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(24)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(25)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div> | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------ | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                  | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                       | `{ roomId, content, files(9), replyMessage(10), usersTag }`               | Sent a message                                  |\r\n| `edit-message`                       | `{ roomId, messageId, newContent, files(9), replyMessage(10) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                     | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                          | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                   | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                           | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)          | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `send-message-reaction`              | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (7)                      | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                  | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(8)         | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                     | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(8)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(10)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                   | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                              | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                              |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                              | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                   | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                   | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus` | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                              |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus` |\r\n| `room-options`                      | Replace the template of the room options                    | -                                   | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                           | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                   | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                   | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                   | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                   | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                   | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                   | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                    | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                   | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                   | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                   | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                   | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                   | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                   | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                   | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                   | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                   | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                   | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                   | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                   | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                   | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                   | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                           | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                           | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                     | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                   | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                   | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                   | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                   | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                   | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                   | -                                                                                                                  |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n#### Angular Setup\r\n\r\n```json\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"035c8a3e17770167256b923be6944975fbaaaf99","_id":"alispig-advanced-chat@1.4.5-bate.3","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-dhk3zR4Ps5qXjKhrvPxvm/QzME86hs5PmEL1mosQp/NY+i0f5ksUZEk9PccdbvLNzZ9UeuCQ9i621+VqvASkbQ==","shasum":"a9a94e3f8f45e218f1174206614d054ba762e301","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.4.5-bate.3.tgz","fileCount":16,"unpackedSize":14780849,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1ClaCRA9TVsSAnZWagAAMmoQAJiHyDX44um+RW/woWRY\nzYYJ2MctCzKkODl0+X+O+bIiQ3ww4NdZMFmZs7bnewDh9U/02G5E4TpBN+Ye\n/nkVpu4HcL/Dald5lgscerPfJ1nJydimlr7Ah12HtBgYFp4zAm7q8/nv8fhy\nR3J2cHAw8B0mKUdYhRlOoMjfKh5Jis8mUn9LycLFpWdqIWIeprefyMGwg+Gl\nmgwLAXOUigeXYJ96B3KuYxiPca5GzSRbhAbTSzTHJTdEWIUycM6fmOBSECNm\nKrw9ZBlcsB34NvNEpXGYC4TSD/O1znEArvd5MERfe1IFxbG9+OlWMkujc0oT\n5uR9PcQS4fQe4cievaftCQHbKf2zshMsKhj3rCBvahTBatcOWqe4qPhMzVL1\nc+grHwS1cMn7CdkVtZ6VNd1Y3frMsETdrDyr2kixISfvFYV3l7zPm9EdOqd7\nmKRuuJnmQOJV7TBakNxhRBF6cTSkWRmbCzaNPvFeniLZytJ7vARdjDCgEaKu\n456KcU9nzl7tqmqvTvWT03iCzDhOuEKBZ4Xr37g3RR/a1y6Ddh8GdAfeG4BV\nI3taWqiCjS9KGEZpcyLFZvXDT4cDNQSs7gPKrxUFaTHBgo4OXMmxstYu43Nq\n4LMcwJ9MZ6zS/FL3F82Czeu8FmvDXzP0sRemGwzVaj/6Ityk3DsnYgOUpGnC\nmIha\r\n=O1iw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHA4+8roKCAFXafbw3gJsMqnwb4HJhOJqYy8xZWtQZ6aAiEA2IAni2Lp4tFVllJ/iIdNulzAQUMPjc3pmSTBXgzOC2s="}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.4.5-bate.3_1641294170018_0.31336458858112226"},"_hasShrinkwrap":false},"1.4.5-bate.4":{"name":"alispig-advanced-chat","version":"1.4.5-bate.4","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"^1.2.0"},"optionalDependencies":{"lamejs":"^1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `messages-loaded`(7)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(8)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(10)               | Array            | -        | (10)                                                                                                              |\r\n| `templates-text`(11)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(12)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(13)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(14)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(15)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(16)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(17)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (18)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(19)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(20)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(21)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(22)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(23)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(24)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(25)                        | Object           | -        | (23)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(8)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(9)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(13)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(14)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(15)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...'\r\n}\"\r\n```\r\n\r\n**(16)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(17)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(18)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(19)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(20)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(21)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(22)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(23)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(24)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(25)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div> | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------ | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                  | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                       | `{ roomId, content, files(9), replyMessage(10), usersTag }`               | Sent a message                                  |\r\n| `edit-message`                       | `{ roomId, messageId, newContent, files(9), replyMessage(10) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                     | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                          | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                   | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                           | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)          | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `send-message-reaction`              | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (7)                      | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                  | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(8)         | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                     | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(8)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(10)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                   | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                              | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                              |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                              | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                   | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                   | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus` | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                              |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus` |\r\n| `room-options`                      | Replace the template of the room options                    | -                                   | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                           | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                   | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                   | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                   | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                   | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                   | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                   | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                    | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                   | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                   | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                   | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                   | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                   | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                   | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                   | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                   | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                   | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                   | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                   | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                   | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                   | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                   | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                           | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                           | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                     | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                   | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                   | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                   | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                   | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                   | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                   | -                                                                                                                  |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n#### Angular Setup\r\n\r\n```json\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"035c8a3e17770167256b923be6944975fbaaaf99","_id":"alispig-advanced-chat@1.4.5-bate.4","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-Q+ZLfMR9EJB1tUwR+F8xS6oKHbJZgx17hiN+uZoJmODBB+Y/BkVXJ+oezsZ97I9LZbMMWyVbHpy0J4vLRYaUMA==","shasum":"d9355ef16cb574f316a2b93e90b99a7afc12e7fe","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.4.5-bate.4.tgz","fileCount":16,"unpackedSize":14780849,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1DAGCRA9TVsSAnZWagAAE38P/jmXmqMP+fu7oRaAIcq9\nZvAcqpeDUnFoDq+U6oKE7+7HJCcN6azHf26QdhHs9UK9HQQu0RcRiM2buzd+\nld2rC+ujcVVRtaFPUpolDihNZT92oplCU3Wb9b24+xhx58TLIVxOlpwGLKbH\nKbQ1poRkdMVgP936W1B3UdQ7LhkIs6MW+rnt1gsu2C0OZ40POOHxPIJyVH6Y\n+9a3GCqdulI8qTfpIR6QkPouD88OXCgl3cglsbnqTixhqxE1aGjH0vN0g/M8\nTAs8kwBr+CNPnBZsjpXRhO47EI71txThXhHbJSlAGY5wK/tCTD9aPA02+M/y\n2FYFtkIqNPI0CrQD0vppo2wUq7BeOQyL42YE89sjPxLmZrDAkJEwn5QQ16Vq\nmuIks8fNTs+rVWjW/KDovf3fryQvT5cUd3hu4eerJwYzpQ/4x+L18UkMR328\nVUqOlNH9tmtFRpk5enApwG0RbQ3BrmG5GwNa5bzL7t7AUKMzRimDNdfR/9Yp\nYrot4Vhm+TCWwE9gHt7n2R4au/iNql5QgsF2P28z7UzErJI0ZB0Q9+6AQlJw\npCdq8436nxy+7+z7sdsvj275qQ+5wp4wbNB5MbDraoP/3tG6Y/zG7q7TX2KR\nHGWwBbPJDsbssWRqchq0Qpekd9gvscfKI8q0enRK8tyLgLqFk9Kpq9rnLbqZ\nPpiA\r\n=60iu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG6MTMp2d6cdKno7NC2BgSVuAZOH5VhxHNmcMtBdUfZxAiEAjCjSLPRSRUSkTS4txAYz465D/bfiMd/lSH8eURrBWfc="}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.4.5-bate.4_1641295877773_0.7622917291290987"},"_hasShrinkwrap":false},"1.4.5-bate.5":{"name":"alispig-advanced-chat","version":"1.4.5-bate.5","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"^1.2.0"},"optionalDependencies":{"lamejs":"^1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `messages-loaded`(7)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(8)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(10)               | Array            | -        | (10)                                                                                                              |\r\n| `templates-text`(11)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(12)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(13)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(14)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(15)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(16)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(17)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (18)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(19)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(20)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(21)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(22)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(23)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(24)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(25)                        | Object           | -        | (23)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(8)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(9)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(13)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(14)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(15)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...'\r\n}\"\r\n```\r\n\r\n**(16)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(17)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(18)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(19)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(20)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(21)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(22)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(23)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(24)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(25)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div> | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------ | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                  | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                       | `{ roomId, content, files(9), replyMessage(10), usersTag }`               | Sent a message                                  |\r\n| `edit-message`                       | `{ roomId, messageId, newContent, files(9), replyMessage(10) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                     | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                          | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                   | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                           | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)          | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `send-message-reaction`              | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (7)                      | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                  | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(8)         | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                     | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(8)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(10)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                   | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                              | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                              |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                              | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                   | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                   | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus` | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                              |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus` |\r\n| `room-options`                      | Replace the template of the room options                    | -                                   | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                           | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                   | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                   | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                   | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                   | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                   | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                   | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                    | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                   | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                   | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                   | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                   | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                   | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                   | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                   | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                   | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                   | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                   | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                   | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                   | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                   | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                   | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                           | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                           | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                     | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                   | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                   | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                   | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                   | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                   | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                   | -                                                                                                                  |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n#### Angular Setup\r\n\r\n```json\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"035c8a3e17770167256b923be6944975fbaaaf99","_id":"alispig-advanced-chat@1.4.5-bate.5","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-zSXbGPzauV/vlm3mBErVUuaBCrVSqZBB/iyY0xutNzkcRkgKk7swcPjAXTI2wnFPsob+wkDKk7v6tDNpdDgcSw==","shasum":"c5f812fc61bbb58507e743aae3d439748d9318a5","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.4.5-bate.5.tgz","fileCount":16,"unpackedSize":14781274,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1DMHCRA9TVsSAnZWagAA9tQP/0Zjw45BR3GPmHvJQFjb\nU18LCEce2FcDpgtGfwJ2KFQFG1F7PiLgokUDv6OrnQQLVi0s49BIFSLMzHRH\neRL3O6vxAEMhz1aQ6X1otUrSASpA5GR5r8cFDeNqact/8I7fw4uMteWJgGtK\ngHrihK8pQmpSuVacu6JQvLyFzmOfZMpiwoyJi+D1G4TyHv8aJg3jugpaUGWC\n9ZbiLziN0E1xP3bXqobcVLBLyo6lzGgQLjYpdDEa0RXXm0HZGZDCeuCj6/Mv\n7g0F0cIcnZ+bfi0NgTTqUOSp/Da22Owmd30tAkFVwtfPHjKzFTGr81JOxGcO\nwEfocoRP2QMz5Lt4U84W1JURSSeMPSIdh7cggVhnoSzYJcRYsjIrbmPRlOow\nvvSiO475zfHPkj1cfmG8JlrwNfmKlR+u1FY/FzLK1NeTYUeWFVkgg4X2+tBt\nQPzZuBTt6di/V7Nv3l+Wv6AJusmvqkUDyr8oYmlGSRYcbdx7VF2B5o3L6Kma\nMlbaRMoBMTUy27VgRTr/JFxJ8kvlqzJ7+zd5CLp1IDlpCI2aTLe0pR3abB1Z\nhuzyC/rnGW1vK/+wQT/qOiZEUVLm2K7od9CXL3loXaG3AUL5e1J0H8lBSyUl\n5WhRmEFG1H7N4qzeSjsOrQjB0u3mnOtHn13gP56lAyDyzgJTqrFvmL3VtLO6\n8TdP\r\n=PC82\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCIk9OhYB/Z+m1uI9OAdIb+tARMXcB3vFVyIUjITi/TrAIhAK560fw1cQU8FKP+9c8Gv5Vtug1bRSX7vFvS0ftPBfGO"}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.4.5-bate.5_1641296647671_0.7184439894765537"},"_hasShrinkwrap":false},"1.4.5-bate.6":{"name":"alispig-advanced-chat","version":"1.4.5-bate.6","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"^1.2.0"},"optionalDependencies":{"lamejs":"^1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `messages-loaded`(7)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(8)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(10)               | Array            | -        | (10)                                                                                                              |\r\n| `templates-text`(11)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(12)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(13)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(14)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(15)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(16)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(17)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (18)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(19)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(20)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(21)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(22)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(23)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(24)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(25)                        | Object           | -        | (23)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(8)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(9)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(13)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(14)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(15)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...'\r\n}\"\r\n```\r\n\r\n**(16)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(17)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(18)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(19)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(20)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(21)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(22)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(23)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(24)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(25)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div> | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------ | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                  | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                       | `{ roomId, content, files(9), replyMessage(10), usersTag }`               | Sent a message                                  |\r\n| `edit-message`                       | `{ roomId, messageId, newContent, files(9), replyMessage(10) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                     | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                          | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                   | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                           | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)          | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `send-message-reaction`              | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (7)                      | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                  | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(8)         | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                     | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(8)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(10)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                   | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                              | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                              |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                              | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                   | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                   | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus` | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                              |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus` |\r\n| `room-options`                      | Replace the template of the room options                    | -                                   | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                           | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                   | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                   | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                   | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                   | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                   | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                   | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                    | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                   | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                   | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                   | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                   | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                   | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                   | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                   | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                   | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                   | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                   | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                   | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                   | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                   | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                   | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                           | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                           | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                     | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                   | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                   | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                   | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                   | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                   | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                   | -                                                                                                                  |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n#### Angular Setup\r\n\r\n```json\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"035c8a3e17770167256b923be6944975fbaaaf99","_id":"alispig-advanced-chat@1.4.5-bate.6","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-oaOaa8nizZ5Q57I0R3OOfs3O13TgQwzi04iQUV6C/pNTHWsPI6Nsk35Z6RhQLEdl0aOX0DU/m20bUBalbaaXKw==","shasum":"45f3889a15259f21aea1ff0e878306b6a1f1daf3","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.4.5-bate.6.tgz","fileCount":16,"unpackedSize":14781793,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1FvKCRA9TVsSAnZWagAAA2kP/290WgpRqEmcxyW+AobC\nnfXAPZAD2JEF50+qnkqUe+3Q6Dk5Vu878/f6tJ2qhX2lefcDM2LiHVNalU+D\nydEZJ8HfSE3QvTFB1C7Fbjuu1DeK94SPdOpJ9D5hmR6Hg4VVM9D87zPg7EUh\nsEbg46ngSqXcBZsly2tOiQQXuT4eJhN7Foi4m0h9jB4t6SmvkWkLheWicZ7V\nzMRYR85fcQikEQP4m7PiBHPX1ytjOD2+jDH5AYTuti3DKfBC3j50tu2ByVPS\nb56FFt2BYUVxNJeZP2GDR3jQDmJf185e7TL3ksXiU80vE9PH/e/1wxYGoYXv\nRBXjp02UQRT7JZf1kPLiQn0TAHoXEhkAgAzBwbcgXhWxNB73aZa+vtInKTvE\nQNpPROPOhGTeob5TSr7QT1xJ8ArCPLFM8o45cF9XDQGgQUkH8wtnnmmVyAPO\nsLlI5gPZlVoVgibWND0OY/BJvmfpR2T48Ur9yv9ORv+CnhV5HnT88p4qL3Fg\nZAn1jdnP/Ev03kZt1Pjwt4fOBAw6oaDQtzIKHg17xFO6mx7/Z0+W/RFLHrPW\n7kfY9De0Dzh1MjNsRIAMFhpB8hxbI4DzNcddUwGaOU+wj+4tOsdy93qiR37w\njKYNzbChmd1Mzfd0MDR3dUgEmh2LYVWUGrfm5YXD+LazVR5fFcefrrELfiU/\nBeEp\r\n=GTnK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFh/LOIwUaxgYiuJ/l+PK6jlG2FV7yfzWioMKe9N1fo5AiEA/VVd4FkwK4SpBDGwUV/10jP83dAYUcux2a0w/s9Xv34="}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.4.5-bate.6_1641307082271_0.9312862268326907"},"_hasShrinkwrap":false},"1.4.5-bate.7":{"name":"alispig-advanced-chat","version":"1.4.5-bate.7","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"^1.2.0"},"optionalDependencies":{"lamejs":"^1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `messages-loaded`(7)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(8)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(10)               | Array            | -        | (10)                                                                                                              |\r\n| `templates-text`(11)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(12)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(13)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(14)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(15)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(16)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(17)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (18)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(19)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(20)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(21)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(22)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(23)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(24)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(25)                        | Object           | -        | (23)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(8)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(9)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(13)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(14)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(15)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...'\r\n}\"\r\n```\r\n\r\n**(16)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(17)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(18)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(19)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(20)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(21)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(22)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(23)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(24)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(25)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div> | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------ | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                  | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                       | `{ roomId, content, files(9), replyMessage(10), usersTag }`               | Sent a message                                  |\r\n| `edit-message`                       | `{ roomId, messageId, newContent, files(9), replyMessage(10) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                     | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                          | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                   | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                           | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)             | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)          | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `send-message-reaction`              | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (7)                      | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                  | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(8)         | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                     | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do whatever you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(8)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(10)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                   | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                              | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                              |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                              | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                   | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                   | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus` | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                              |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus` |\r\n| `room-options`                      | Replace the template of the room options                    | -                                   | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                           | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                   | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                   | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                   | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                   | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                   | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                   | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                    | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                   | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                   | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                   | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                   | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                   | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                   | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                   | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                   | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                   | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                   | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                   | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                   | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                   | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                   | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                           | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                           | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                     | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                   | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                   | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                   | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                   | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                   | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                   | -                                                                                                                  |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n#### Angular Setup\r\n\r\n```json\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"d3e20d080942ab96446b7b01cab8f6f18573b7dd","_id":"alispig-advanced-chat@1.4.5-bate.7","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-3iAq8pvlVm7yWB6h3pPJMNOTQ3JJUnhJtVvChZYBTmJKF4TYiP5QccFuH/zn0YoC78lwE0GTBHWdy6bdoDMuQQ==","shasum":"6fc5e36280ee83470b366114e705b03a87440c96","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.4.5-bate.7.tgz","fileCount":16,"unpackedSize":14789333,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1ThwCRA9TVsSAnZWagAAnewP/1U1h2obruC5GBdRoXbo\nLye7VGBAq7qrZQuGTV0fZRQjtEY9h9t+/uxCA9uM4ZZG/EI03vkUgvEWwmC6\n/a6bmx7KgW0lJZFJOmjX2DlhIlIJ8ZJ35g7qr+3Sp03Z6ya462JF3yldw4HW\niUNvBDOvN4/JkQujeEhRXopWU3T/g5RBwL4NaJKhkqTvQYm2KuNI9IxzMmWp\nBvozYmMHEnYI0rhuA0p1D1+Py+8R1rNaNw9gmGbPktrydYAy66/CHnAf1HIu\nrFSqzGH1nbkY5sitESqnUfnbDLyd6qAxPzgG/k2wOyV0jSk4gi7lyazL8Vix\nD8okZJdwBfgPnq8UwL4bprUQ0vgRlcAhOhezKn9wv4J5MSoHtqaUIQjBtAia\nR5cceX/wtPUydp/nnbATjv+6wAGkIi3jeolWFBj65MHCb/WDjJwTIh86TPJ+\nrU8Bc9kOnAW4tpnHAtorwcJc+vDjPBdxAqD6RsKVdMwzFcXQ6EMiSOO/naJ4\n198lg8a0R6OMgqCOpy7v1f7nJ7xLll5yJGWXCLdc4yo8esh7CEI0O7eG69c6\nS7Fgakt6WWq4YSZjwpLXBDdWYDLzddldwhOFKWAKw1BQ9m4dgvvc7bAOQcoc\nf62QRtEbJy7CcshSoQuTmxsdBv4CQpp5JgqdrI6bxIY6ZwZZmPbuufkn8Vwi\nkSmq\r\n=kHYx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCHGZnJZ+/DIU0GaiSmhNYFzNYX2GonpOHLQgLMZqygfgIhALuLDuZ3W1BQKwlwOqakLBcLju7XKJFNWSqHrNcR4hVc"}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.4.5-bate.7_1641363568424_0.525951978279777"},"_hasShrinkwrap":false},"1.5.1-bate.0":{"name":"alispig-advanced-chat","version":"1.5.1-bate.0","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i --legacy-peer-deps","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                   | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                              | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                              |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                              | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                   | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                   | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus` | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                              |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus` |\r\n| `room-options`                      | Replace the template of the room options                    | -                                   | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                           | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                   | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                   | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                   | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                   | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                   | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                   | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                    | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                   | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                   | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                   | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                   | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                   | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                   | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                   | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                   | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                   | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                   | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                   | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                   | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                   | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                   | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                           | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                           | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                     | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                   | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                   | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                   | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                   | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                   | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                   | -                                                                                                                  |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n#### Angular Setup\r\n\r\n```json\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"855ae3f516ada8f1f47aa66e2732f7310c798343","_id":"alispig-advanced-chat@1.5.1-bate.0","_nodeVersion":"14.18.2","_npmVersion":"6.14.15","dist":{"integrity":"sha512-OZ/O7FFWO3CTkTUtXw5e0O+LnnH+6pKQQrKg8XGukOewSNOWyJl03bxXAAUtVAH1VIYfVLcgywYnbqJ48/Ae7Q==","shasum":"1ccd27d5f3b413629d986e60a32fc29f459834a9","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.1-bate.0.tgz","fileCount":16,"unpackedSize":14935918,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh59jfCRA9TVsSAnZWagAAS4gP/3YDaucrztt46LQ29AXg\nblsLhELabjq968VgX/OsflmUP7h8AQBc0I8z23xqgMqoJwstNsHrUNE9fVO0\nGqmjE0YDakL9g+GU9hyQsUXsKWdvU+OLBuQADCWyTmFxV8Ww/bK/O07LKmDd\nMzTIBRaVyOme2VTHmGWRC0393Wg0B0PbtSyjFqtNmBPteQgEwNqkylqmW+tC\ngMKDnIlN3zH/O1+piU0qwwx6yIhB48viffPJwnC4F1A978r1ewN8tDupa/eS\nccKucoxNC0W1J7IjS+CT827QkaUNerVoxCq+g7SRuv3vtIQjxIY26sxEUTkF\nOBwJyTp6+pvUYmGFc5qHgQOubp8NL0QAFrUi6rbIfTvyS7fuDEwA8xPVl16q\n6/TqJThG46t6aJJCkNzZ9Uh4N1aZLdKbIA7zu7xDNerh9BzGy1+x9k5X5czL\n9QOeLCz4ksK3ndwyEKKmTHiF7ovZsT2PpsjYkY3hih6852e9HxNpZ8JL7apV\n8IXZUbLrRY2qXhzoY20lewPak88t9E2t881UjPVnNWjEn09lbyUJW/ZprTM0\nfD6Hl+2SPvCI8lHvPvqRl82h5pq77kUn6PTC9YNEX4sQSXRiIwzULns1rCiB\nRGIhiLlyjHnrT5ejn/aLt1y/LejXrgU9laAnjkyL2p+8dF98eFkOoiyt8DLR\nPwDo\r\n=XXUF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDUS9HFOthhKCmZWPSltoNw0IwfWAfFnppdZT/fB0p0cwIhAMfdFcsqyrC34AWqxaljYQw7g65bSL6M0RDfOaYqfoVc"}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.1-bate.0_1642584287056_0.20298628097414095"},"_hasShrinkwrap":false},"1.5.3":{"name":"alispig-advanced-chat","version":"1.5.3","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"emoji-picker-element":"^1.8.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"7e7f6729dca949fff7df87d6a42bb64a4e1d77e6","_id":"alispig-advanced-chat@1.5.3","_nodeVersion":"14.18.2","_npmVersion":"6.14.15","dist":{"integrity":"sha512-Sjznua9FFJeBmY5qI0NNNIgvgVwG00zc2KH3mxmfRD65EEqpmm4vZXYJk8VFZtSVGCMNA5lBESgBDy+9Js+j6Q==","shasum":"b1b3de212eed5f03fc130d7b83b52b173829051e","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.3.tgz","fileCount":16,"unpackedSize":14945064,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiJNGSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpduBAAm1rm+zhT2FxffRZmrgeoW88xl15CvT0VjdDwKgpIp+AIDQuM\r\nUgAmaowqxHh159uTx1MKWtbNpz1PCLccZWEqxZR/rPnOXbDZFxCx1EMJgEV2\r\n3k3zPwkEDqmPrGhypgS06uGD8Eab/8kwax5DGRszK5I92Y0ojS8YZMhsWF6d\r\n3/fNNyEif9YX2F8mBE00rmtHTqkv8enH+Fv8Zr6J+Mu04TwrYyS8fKbOHDU8\r\n025N3mL+lUcCi+i5PISL/+M2BQAqokU6F9EgTk4U/ad1hQEtpFBwCsv5AwpI\r\nMeNajAjwE54vm+IeWj3r4hP/yi2qhHwWBTo/IfKRoZcBSFgXVPaHqRwfxEN2\r\n8TlArzwpmfExDG5PeYLPGYZaYU/v08IhHyzg+SLxXLbbYWKueaAmTFUYu2eL\r\nCKIAhdTNUvgWeOlkQ+uW5kCwPP42yKWdGwSb4oD9x4dDY/VKFHa+HEbkEOjZ\r\nqlUxqiSzvggNonuUajzIPRPAVtOVYCc+qu/fhIA6jv42+1rGgTzsN5QnjgG1\r\ncVXThctr2P2vFebJmZ9ONwhHwuwtSP0AXU9ZGAc9oKFx0Wx+OcR1Mj3nDBTt\r\nY85GQYTFC5I2UX3u7k+t8Xzgv5qDlCHDr0iB9AIP/qnKdo5CMt7GbQ8cCJBi\r\nO2hUIy5TDNTG4pbCeZhERrej8fu77pXa/MY=\r\n=68Yd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDc2U3S8WKzUU7OmDXJ7pQz9vBLB/yahOqxcaai6Kh3qQIgVVbOXzbABiPhe6OQxrj5+zJwTINffAV8rZt7690Ye1M="}]},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.3_1646580114052_0.5561303640530029"},"_hasShrinkwrap":false},"1.5.4-beta.0":{"name":"alispig-advanced-chat","version":"1.5.4-beta.0","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.5","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"ea0787fd2d297b23c59d82a476d0e41810b5b6e8","_id":"alispig-advanced-chat@1.5.4-beta.0","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-UjfoekIDBPflPIIWYYkV692OIsfLhr0qOj+MnjLMmxY+JU1A41woytmwsgHbn04ArUOSJ9CYjfGWyQU4GT+kVA==","shasum":"29129b6bc27368e81dc7e193463149afdff9115b","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.0.tgz","fileCount":17,"unpackedSize":21693353,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA5s4xlMzgQqCH3iGwGu0/88p5yrRKle/3fOwT0KgnlmAiB0AOUydFsahCfM4ASN2tcNOtvM774Sh8EDZN/gREl3tA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiW+q3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqA5g//aq/ht8WK0KQSjZ9ygw5yi3cqqBJOnACujEXBnCxyH0egcqgy\r\nl7IUX+LPl2UY/UAjwkZKYOvAmZbb+PM6JUXBKRRwwD5EEdIShqH9fRpSfPWB\r\n8ytSMY9z3lrux257tFSX4vlKE6ZtnASdtl1zqkxUEQZ49r1KEzu4klJniNZn\r\ne+lc3SQizzxFq1DM+as1MYtbIjPIaSrqijPM5x0mnINwWwUSQ1866RYOjNbU\r\nUwkuzyquPTw7fyfSQE+suxG/ubMuZAqp2xK/tE1KwiLubHyZTBXkqd3CSi73\r\nyW8F0NRSElBWMADLrmA/ESoTl8qByKg9WkxIkD5dyTfX3CsWyJ9m1hE7P7pG\r\nJAKtpiXUWBQF4Ut90J2HV3gYjumM9HpN44Tj/4TCxmIC+9zvOAGAOhRI5M+I\r\ntHC3Ad/BxWzv60s/DxHaojDR9W9jB01Aag5MH0cguoRwXwFBfF5CwdV43dwC\r\nZDCkYfGLYS4wENanB6LSYSNu269ljcmtSH5+Rf2hsakEiZO+a6OuOr/djF38\r\nYp8m5w33jkchDPNTK/n9yoJBROIRnqct90mRIcZmV76LGy+5enbVnc/H5GH7\r\nkgMhiMfgOYEDh2JxfddjEN9ICeZpNNNGuEYTW7wcRNgrTovKgRRPEyQ6z2DQ\r\nT+h71nhHnRVVMAqirsGx/+AdUgcuD1fdxrY=\r\n=Uey5\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.0_1650191030746_0.30860908242917073"},"_hasShrinkwrap":false},"1.5.4-beta.1":{"name":"alispig-advanced-chat","version":"1.5.4-beta.1","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.6","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dfeb6e910a3ee0e69bb7ff92737e898eabb49a7a","_id":"alispig-advanced-chat@1.5.4-beta.1","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-i9LaVCoDu9fITlYvW4fEb3HhEK4sZUbiWyTlkFXu06Lrth0IrPAVvgyqqudXeYnpsHhf6XQ+/lR4RIH0jBpj7Q==","shasum":"653f533f816ebbd570d3c913cb31db2f399cf786","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.1.tgz","fileCount":17,"unpackedSize":21694037,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE7PmFUBa0ldlLVS4w8JtUtvFWOxgXGlmKSaa71OicgUAiAJZNF6xqk2u0DfFY1q4ke0ZNtISTKtSJP2b6QR9A0ALg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiXNC/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmplVw//RxZ09J9CltIrpKil9uFkJkNiV2MSMemqCXBUqQWBq9xT2/3M\r\nQ8Fe5DsYSYqz1G8D4asryvKtBQ2GpMGlYzkXnj1bufmlp/NykRjRFkhhmwEP\r\nQeRc14cvnllEUqCRGjHKJvPzuq8ymhptnvZ1SFsXNLMepkUj+m2MmKhghhWQ\r\nPg/jFGCxBUgiC7mO46jfpUuVMmOQqv6d5HppixE8kFI4AxibE6RgZmWVHQ/l\r\ngK0oz37zKWQHIWCDb3PsbA+0p88EajFvG2Mwb7WzFWOah99S6/0AAOdmCzXC\r\nlPhij3j9qtsVA3AsZsCfGlVOcKJfHIFzP+I9C8I2DNFtBx+eIgcSvXU8A0qV\r\nyR2HFnn96649WwJdkl4pfYqKl3X11XdBjbtVceULdNJZqmHOZb2Rnnn3Qhfq\r\ngjw6L1+7fNgXiO0BJTEG4vZeNfvwEpLU7RcC7Q4zFonfAT9vRMNRWkOJ43zn\r\njUdMQmTk7KScsP+AHIxd5/E6/+dvg7Lcz0Se7fSs/5YEGc0K9pxsfuq4dpSu\r\neCzPiNfh4fg3FbNz3pGneTxOg5zF8vQEC80sMIlqDPE1RhiDa486cVH8JqqA\r\nqetUrmzL5RdMQ2npM/DZaOtQUF2mmMW8CKAQC6zhOp78+cy4fdj7sUfjsFB7\r\n3Kyt4Ltd+/f44JE8YV0HdWIpf6z1MdEnkrw=\r\n=nQJ3\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.1_1650249918953_0.6604239561902439"},"_hasShrinkwrap":false},"1.5.4-beta.2":{"name":"alispig-advanced-chat","version":"1.5.4-beta.2","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.6","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dbc2ec938817d333f7ac680fb9e646e82f9957a5","_id":"alispig-advanced-chat@1.5.4-beta.2","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-HFfAr56CKZbHdOASxXULnaNRlkbLomE+k/QSRr8T4SjFXVlbBOemcoFpZd3ACSR3x3iv+o89BMc8GQ8uCE8t2Q==","shasum":"079beb00eb5816879d628dd2f99629af211da591","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.2.tgz","fileCount":17,"unpackedSize":21946469,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH7QLX5vZ+ChD6XO70rGlSrmiLhGw4fsy1MVcgAwfyjOAiAyhHaizbuPpx7kBmRpt47KGyE/yt0zFo3DvtNEn8Jtuw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiX2lfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqYuA//WjByyBft9gd4afTKVL30NzN2eBnCRkjW3+fLXu2qbgO9w0Z0\r\nB7gTrSvkvL/QpJSEIMpW6IfaQ1V/PE0AihY6Kou9UoC0h325hA1kDvmyf96Z\r\nvd0CRmj2LxnrKPmUInV5/sK1r93DMSmhVKKvYPbt61Xc8SWTsgGjNTgi5fnB\r\nBKjdtGwzBl5w82XCZ9S1JMO8jli5BihnRRnDL/XQighPmefVGt32LpkymjiW\r\nTWJJGI51AfkChYujUvKTNVSoEAZkTcuT4Bve1gikEE1qDkjoSYB9rhmsQq3W\r\nJTrwUHyNgQpttQeLzG3G8+wbQwEroQv5Yht9K6fF7+9Lek7mBlf+285jeT4+\r\n/wLJQs8okF55MtqqKe3RqhaA/uYCwOWY+SnUuF6CXUPo7clBdWG5/yo5iLo7\r\n0fEFHjbgFhHPSfsY4QZaVbiGvFtBC9RqWDyd1/i1ZcDg4+WKIPPFCg++QRZ0\r\nEUVvwMfO/i/7RSaGGaExC3sXX+xCmYAVX3AuhlqEuY48vLQNl0SDc15Jkowz\r\now0CbB2HelyLzRK55Pe71qCc4nkfjWKKRzR0cy0HnnUgeD8Exd6y7sJlfdpw\r\nJs80tZk2qtqp8yC0fcd3+JlNgJK1P7LXNC4MzvluHjcCbDyrhzrf062EY4WI\r\n4OGotIB2pSZfbGjTUXDYKyUovEft674KKNI=\r\n=YTcn\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.2_1650420063381_0.5449628892301777"},"_hasShrinkwrap":false},"1.5.4-beta.3":{"name":"alispig-advanced-chat","version":"1.5.4-beta.3","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.6","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"9cbc2186c40cdfa148302a23c323e0194a2bf7f6","_id":"alispig-advanced-chat@1.5.4-beta.3","_nodeVersion":"14.19.1","_npmVersion":"6.14.16","dist":{"integrity":"sha512-dQTCg6dd/26zBMjWbJXVTaNFdv8Z/6Ax32FLQ2vboDFGx82w5RTpbgBxS92WkQrGy7Kzhmfx1DXUk+rezgKseg==","shasum":"1f0c4396a2af27053b58a0e767ddcec3e9773df4","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.3.tgz","fileCount":17,"unpackedSize":21987155,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDwcZDw/wGKu2efT21otgU2HTj28SDc6tY1tJwBrhF7CgIgUHCtvs3YB+RHy2MONLE+g9JcymPBMqYd6twBUFUR10w="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJic5haACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrNVg//fCfSVoHg16K5TYjQRn+VLsKaWE/IiLg8s/bosk0sJ5gjW8Q0\r\navPpz8JPNP04J8htgJVPr3t15vbLHew1oRYOgbHwPIcBUwXuv767ZLSJ7nIZ\r\n5IJ9do/WKoZocbYnKInZ9TdWQIS+YK5o1St/b1sjVspyPHYHulLyjm9ckOpc\r\nQDon/5VjfEJ+UkInno+vkTXVnJ2sQ/ilCmb3GhHqbpg3SktQZnTdMQmb233w\r\nRV1DeoeExyjBjAm4ykiDnbaThIEvgu3okjqitICjPQ3erPCuuUfNF+2dMlqv\r\nQDZ0ya9tHC7r0TyItrnZ/+VIwUnYtA2U6zMy6PefrMLybSa5PFe+9vQggRxy\r\no3m/9oc+8f7LscSK/qXNaJP99IAXymmU/hc4WUEpjGdfjCfvF8QI5+6l+evg\r\nWA5RGQrlmn5JJZ+lTyg/jJxYm//r/U777MrwzdSS+s62/8odZQLWtV7dPPOu\r\naCVbwzHzpd7gHMWuFHS2qmc3YvPR3SAnZrDTZaxpdnue6YyLtA9kNToSDbPa\r\nnTNCrp/d3h4ITcFkpCMYhZcpjPhd6VGYXxqs+/qj6FFEw9L4LSbhIcEGrOdb\r\nDNKzYq44nbK0QH0GwBfjBYjtur8Bg/O8BTDmyBE7YrlaZPVj80T+BSk9OuGf\r\nIOQqtyo2nRNqu/kMCivMUcJSZFB14edHmO8=\r\n=PVoH\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.3_1651742809810_0.7296109746695285"},"_hasShrinkwrap":false},"1.5.4-beta.4":{"name":"alispig-advanced-chat","version":"1.5.4-beta.4","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.6","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"d76915969a9f33f6cb35d9e9969547b6b610a40d","_id":"alispig-advanced-chat@1.5.4-beta.4","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-8finthN/hizMNaXwRlLMKxzQOJD3bJFglKsKTrL4V7QFgcI2NGjW+XICWPxMsXoEKcv8Lhmi9R+mq/BLMoYJRA==","shasum":"5842a4373a423425cb6aa14d6795b703922951c6","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.4.tgz","fileCount":17,"unpackedSize":22239583,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDzYloyfmD8tES7xMM/mc9r1FBWYbzuiZbnJ3igOlUrXwIhAJ4rLtujYjJi7FG6PHlQs/ImCjQF3r51CgqhSPUz01EZ"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJidiltACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp5VQ//aNCVpkEU0LIqKGIolknEISTHRsB/FmExiIlPiXOD0Fe4fN8c\r\nf/buGH+xXV/sGS7s9jsQ7KVVgc5YdEFyejAI/uYhZ90/xebkugtmOOpxa0UJ\r\nQylOq5u2TkQ4y5nC39EE9FhSgioz/hKeYPruihw9+pMj3+p/RioRcHlisA2r\r\n6x7Xvxl74p7qopV4B0RvH6/KD396PHNNJQ4djWVayfc/O74IEe+MuSIz7Onb\r\nGjqHmS6WgMnNuq9S8zFighlBKnntqoXWyalOAs7Nt3bk4puhXvr/nt+L0871\r\n2xGDUNrJFlvj1SDmmc1cfqG8JKF6gI7oKAba4h8txQ6h29iHaDk0tYPEc6/h\r\n4pkUSDT1aQnfZZEIP4LjuKnWZ7p6fgmjJYzy+fn5wx8RfY6otCkwrHWYfaXf\r\nlOwrVTKuXYzfckaVqusyhEIfuaAFrWMKO8xNk7liZQtV5JnxsvLEKzH2wCaW\r\n79Z8od1/0HoPM1mwpDCfO5zy5F5I+gadO9tL14XXFKN4LK1sgWSGfuvtmV7q\r\n3cPwRMz8Ph50x3VLsN5Fm503agys+uF8e+5NX3XFEvpLxMXWa0qRwWsW9jXV\r\nJsVKHXyCbTsyUXsDJRJq7ofFyydvwETWSJjM/XTruqM7Ta5D3AuMD0/9MxFn\r\nB41sDpdRdzkidhc+HI/A57AC7EXIlwOgjhg=\r\n=Ypg9\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.4_1651911021067_0.08776554994378394"},"_hasShrinkwrap":false},"1.5.4-beta.5":{"name":"alispig-advanced-chat","version":"1.5.4-beta.5","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.6","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"8f2b8f3219ef07539b9bf4f7c39fb987007ac0c9","_id":"alispig-advanced-chat@1.5.4-beta.5","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-61ThUQmr7b/i6krzDRIa0dMVap2I0aQBFCMDKGfbo19vork/B7eChaT8JqRYo1nQ/E7ZcdO1kOqd2JYjIEpykQ==","shasum":"15f4d14e733b3d19ae1f31c18d8dcb63c93fa852","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.5.tgz","fileCount":17,"unpackedSize":22260192,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF8IbC1y3PDFpZ44ruvIXCLbQTmNgsENx/kL/QeiHaY/AiEAjfzQMB1xFMiqbGggILOB5eorT/NL5h+ugPdJDQBW/Ws="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJid33OACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpnHQ/5ACpiHjIOc4fnVYOSiwnCcIvwpfc4eWONFihbOiJEN50N9MlA\r\n5ktEkIvm/JCYvjBZKFZ4pCdfF1ofC1tBZQtjul/WRMz5wLP5ZkJ8jMjaT/DH\r\neui07805uQrTBWtly46rL8uUL5MYC2oyxiRFP/GqW5lT6BuRR909eIysQ26i\r\n8sKS4Y0EWlth+8FCGQubWOdVUKrlGzg+JFEOqK3qNkV4UBgREoHtrCuQZBDC\r\niRwqP7NWwC0YoovbjMQKNgdSAIndjH6q9n3u709TRnDcPeLfib7fPxo7JNRX\r\nHm6FuBKTz2Xex50/gmhOGFoMeqvvKRhGbRdJnKuOxtbaAEmfaQpOyNshVAW+\r\nbaAuhRiohTWpmjsfcZBUOPPZrFlc8ZisXuuhAW16AoTR0JmENbkY5VAiNCvE\r\nqpX94WVDwizd8Lkxm/0AM7cdF4ZiHpUxLbHceA2agQaIbtkIx9OcaHNnI+Vd\r\npyvSEinH5bvjUoWObnBa+M7rK/AY1Vp5fBIl33LBhFOSP5c2KLo0r/G58QpH\r\nyntGrARAXPJQYq2rfqGdoqEHrrRjhzJxQji+T2zcvyqhQz+YkBT9k6ZDL73a\r\ntjyMo6GkADeUU8GUp7NAWTo3hwQQFZKGZskK2RK72B5tpwtDDPRvqMKupHck\r\nk5t0cJEXb3QzPBRjAHIXICTm9MX4GS/Fsm8=\r\n=T85y\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.5_1651998158428_0.2902215065244651"},"_hasShrinkwrap":false},"1.5.4-beta.6":{"name":"alispig-advanced-chat","version":"1.5.4-beta.6","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"^4.0.5","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.6","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"8f2b8f3219ef07539b9bf4f7c39fb987007ac0c9","_id":"alispig-advanced-chat@1.5.4-beta.6","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-wOrINEPPLZYAgTF4WmdI+U8ov+GBHSM4oL4+mRx+WrSkWHnF1cK5cE63tlgnIC8deH5wwra+7NR/YvXnyJ6beA==","shasum":"478dca869ea04223d2506ad9a4381cd57dd3b715","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.6.tgz","fileCount":17,"unpackedSize":22262577,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGs69BijpYbBEwDRr+tLqT5/hEWK7YsMy2rJutb7K2amAiAV5wWIhgUMqYV9TQCPBjtiDU78jN5AkkDgJxxZWJ+qiA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJid4VAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqRQA//Z1r06MIxSvZSJR0uAlE1vf8WJtkq/AaMFba7Y1gCYuTRyaFQ\r\nFudOW8ogHY6nB6V4ri3RbiOCKbvbloGSNcGAsdVgCQ4Di3YYWgJCOnjOs6NW\r\nKQ6kSK9QfaV1yV6JhfNODPCRnXQSRveCCTfIhPDhg7EC7VWRuVSX9/DTY6v+\r\n1oDSuaNS8p8ZCtX8CHwcbxyFLEfchkeQRYSC+2ozf+XL3rD2II9lGW8OuY3R\r\nCnfFTuzj7vESDwxE45QSrjuUS2ZNodBJo5fKvRHaaQvHy0X+gQBVGfe2UarS\r\n9+5s+g94DYpexS/az+kRk+0+naqYRu88fNtsrQxcumb6CXf+0TwHMo+ONXoU\r\nz5QXO2V45tjx6Gsi2L8f6Brg+Zu35xgW8KO66NjmV2abY4CzrMV2Drg3PHhj\r\n2y3So9jqUvcS9EBaiAGYab+lwxg5BQloUftAL5x7AK8+DEF2GlYIj+c2lP1J\r\nYL5aKt6KyaUr5RNfXLppDptu2l3f1Q9auSgqQM/pjvmRTr9xWMuNMtU3FwJj\r\n23nppHipl++q7t5bR5vmQfGi/Qf59KmSv3K/xqhbd19At4KU6cdtjcTe7BFX\r\nUkBqMto68F1QIlGXMAUCDfGhmKhIXAkgVvqxpxNb3Anmn2jMClfI9BTvwvgx\r\nZz2lL5AykL4/SW1c9eYZtnd69L6ch3L4MKE=\r\n=lozT\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.6_1652000064503_0.4622747932319575"},"_hasShrinkwrap":false},"1.5.4-beta.7":{"name":"alispig-advanced-chat","version":"1.5.4-beta.7","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.7","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"7aee5c86c4d23ec3da0527f71640b30651369cff","_id":"alispig-advanced-chat@1.5.4-beta.7","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-qsL6Mxhi6tnfZYKO6WTHqXHybYUFGOziO3yvfiCcGTZ0350AmBksiF/100u7Nr53NCvNJZF16lksG2luokqJ3g==","shasum":"3cb60d95543cd742d9663186de2e4a5d781334c4","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.7.tgz","fileCount":17,"unpackedSize":22307338,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCzh44dirjnQRxYrsJUs4lCvUYEI20W5sC11FsI8d9w/wIgItNINSMgJp93jTNsY0PCPGkokvvzQyaeJboauBy3F1E="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiuTE5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr5uA//YcC+D0PX6Km/QDlNAj6IyW8JkU2MaTqc33HtmvSzQ7QrpGtz\r\nIHl6am213tHJasqyV0CZcOR1qVw4HlWkSIe5kc0xFbSbXq/6f6dt8bcFtB4b\r\nsGCnn0Bygre6Pw+BaZIuH1rRvKmzBTFqV64pywbSa9KsoWNHJSkpaFgWqzH/\r\n50n5bfy66xyI1iLW26cx2hXKpThvjp74t/FTfzRfCu0F38THh3pztZt7lhxB\r\nA9C06tqPDSeLLXA4qe3QXDxuu9h96751ZjLtUOAQvmVZGqVuCMsgAYL9F+vK\r\nWUCgFcflH7x2WkiC8qjLQLkcdhqOcW+ucm223AomTty6EHBkrOL3kCJcNCWf\r\nGtyccTeOoUcXYP2+KZRck2JWCNlgvPZjs4/ta7A2gaiJzJki+UkvzGZNDxm1\r\naA+wNUe4dV61vZOk9KlEvX2pPP3IYAkh9+sAUZ0ewHLreY5NS/Rn89x12jpN\r\nZ9GFLXOe39lR4wGPA4s69LsWedPYHZyQlmXh3tQqjtzYaiH9l3ISAgG6wJzn\r\n8Cj8o0dqHFdKiJ4fDaqN6xrUhbMqwNVVs6BY0dxzjbRqYRzSDa4Bkjz5wx19\r\nAbyatxF9+Hxh0sxUXmN4bOrMLZryN4cmC99CjVLUOa8hWvAV023zwitMlgOa\r\ndj6fpGwaFgysnAEu/QVnbXS+5Pl56hMcpUw=\r\n=oQZo\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.7_1656303929242_0.706659364552525"},"_hasShrinkwrap":false},"1.5.4-beta.8":{"name":"alispig-advanced-chat","version":"1.5.4-beta.8","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"7aee5c86c4d23ec3da0527f71640b30651369cff","_id":"alispig-advanced-chat@1.5.4-beta.8","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-tS0WwRTKWCdMf+1LZQ7L0h7HuSphLP2i9y3TW2ssJf/+DZ+9A0CWVmqpOHflyekf6mTTtTvymeQOiE0/3vTG8g==","shasum":"a6c8063362adf8d548af2acfd52ea8a0a1151460","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.8.tgz","fileCount":17,"unpackedSize":22303781,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBXT1cxFyuKT/5KuW3jQphCVXWJ7WgH1rnuPzERNCxUOAiBsxOMi8FsitNznrscHnVA0xRiYRag4ueBPl3emWuvXyA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiuVGsACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpW1g/7BWy62x5cniGEBf1wQQWOA/ZoCAXUfamsQRwSj2rN9fwJpPsI\r\nfv1mX0T5OqckBCnK/fF0f6NUQVHisA47HQA8SxrXiQ1Zk5R7KQ+k2X/ihe4l\r\n1nooJ2a3dHiNKCgXy8vT9G4OKa4YiD9pU4s4E2BMtKQ4u4D8zLnvRhGUAvOm\r\nd02luUV8cX880PTjVzMozlORQYLJUxlwZDdGNDPLoNmU8ulkffls1fucthP4\r\nl0+N/SgK3EM4Nmk6WTEERTqBflD4U9OBg46846ET5kqqezjIL8t6pSyVll2s\r\n2cavMbt79s4302gK+4HKpkpJ0ccPiqDaWigZz4GrLTbSwCdwHSD3aXqgF8Su\r\nF4P7Bh/VN3u2ENQBo4oZDygrwfTwO5gC23hq+Cxa7cMOY6QWFoqYjDeiH1Gs\r\n2CzQn9F9D4rADNLX2aJwzdBCQZzduS6bRCBpu+triTwUFqb6yXfs5kQEIeUQ\r\nnjWV50lYx93lWAC/TQ5SBUm9gJo8MbeNXRncbWHaqJGL8YaAvovZA7gUv1qG\r\nMrnOwp4R1pFpYJhD8jScCIHgBqkGWW7m5cVqtYgw/aUdiZA4yTg21OGu73UA\r\ncbwu5bDWQ2nOmjb5H0ed2GBZVV1C1z7m0JxyEuvsUL/bugK6xzS0zGSBavoU\r\nmb58jlsjKsE666LZx6D4Ivia9gd/5v6HfKs=\r\n=GE64\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.8_1656312236420_0.635502046118392"},"_hasShrinkwrap":false},"1.5.4-beta.9":{"name":"alispig-advanced-chat","version":"1.5.4-beta.9","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"7aee5c86c4d23ec3da0527f71640b30651369cff","_id":"alispig-advanced-chat@1.5.4-beta.9","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-cv8NSZ+z9d+JmPGfqEHDlxgAzNiFTaaYLIzLXMdD1UpPZc3zTmhQvWNGXQzDopxZenxNsDY0XbZ/qgs4/n3YsA==","shasum":"b4d10ee451219f319a7e492e21ca9d8cf4a4d3ec","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.9.tgz","fileCount":17,"unpackedSize":22303768,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBlDqjG0XDN/7KjYwqBkbY5esS6/sVmUNjZpp+I+zrQXAiAxegmsfpXA0i76ujEtGSr/6ofLxui/xdYdB6GtE0WxMQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiuVrXACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqsfQ//X8KRJvu5l7Fe9Xhgdoo2thKpcXU/IKGlBxetGJWiaZdhVu3w\r\nC3nDf+LTJQPePph/WxLI+Uu4ebJD4su5dlYCQYbfVEM9Hy63PFw4Gfak0kig\r\nAPDHHJ+Jagq7+9R9qNr9anSy2HPIdh70Cg7+ek6rgAlkoiarkvmIf1NfE6e7\r\nLdXL+z26QjbQlUlO5YXVxriEKJezi+Rt2f/qYSCfVu5/0O4rFAKRvBEwwOde\r\nU6N0aW6Lxug4V89iKUMYdT2jVaiNpqr5NwJb6dNdd9ACD3ptmyPtme+4mhSB\r\n4hSG5dvBIWb4mKLxBVrb3YrWygYfkA5Uf2sAiI0r8WLrJtN7Ush3hej24TnG\r\nDIeXcyyJXJ807F0Xa0nSNUKzIIKEChMcsYbd9fWNKwf+Q/sj62YpMDxcCiu1\r\ncpJvjtX0ZEYMlzhGY30689GB6lzpZXNdz/gZIO9tDHlRDq+KDGmLiRfAVjJ9\r\nFRY0ZFuZnFJ5u9WO2UAMKA5QGNm1fvzlNTWH5FKXdcn/0D14c9FYPfxSnsA6\r\nh1r4vlj0qHYXLz3N9E9NAKxB+XzTLihrGMOk8PveNnyBU5ccMIGD8ylJNkNN\r\nztnQvFGuJcFDrhz+rObo0nGN2g9NV+7u9hA+z6zd+bT8i7BNk0rLV7eWegxy\r\nu1PGZc/GDFkwkIN/fCWkSAXHcTQT0ybGFsc=\r\n=VjBq\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.9_1656314583072_0.787579764960451"},"_hasShrinkwrap":false},"1.5.4-beta.10":{"name":"alispig-advanced-chat","version":"1.5.4-beta.10","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dfd4cf4a46643d920c55672ceee2ad6d9cd4d5cb","_id":"alispig-advanced-chat@1.5.4-beta.10","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-yWDGO5TVc6eUe4X5BdDh3FWIXATK+8dL+c+eco5MGocO799UJ4FNGGsU5lIK5/DlT2SMxK8P3n9BTfhINGGsDw==","shasum":"76167075650aaed82ca6feeff47813810a051ee0","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.10.tgz","fileCount":17,"unpackedSize":22308276,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD/NWYKfTxDNU0S4bakrLAnlXvPPESUuwKSWt09obaNTwIhAI8ziLyHGyQNxPXChNw9bkwga1QOPD8PKkgYEuSlwVkb"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiumrHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq77Q//ZotOkhqNncZgLswTybd6QtEcF9lLfMKYPRicOl8qb246RI9f\r\nFPAsvF8i72CY1iHNlhvRq7BS6HExISelzVIaYeSU5qQB7vLIFduEvanaeEGi\r\nGHCxiIBw+ORJMnqIkD5LZqKMDuB5VKDtOdyJVDVc7z1fRArWsiRonsTyorW7\r\nvzYJkTh2fHJSNljl0ceGswDqaNNn45e6SYygyTjXx5PHCOdssxiF0oEPWNx+\r\nT+Rtx3Mrk9cxWkrlzkvYTQ4lWYiSlTmMfN+6siPNhxm4748RePsyl29EWcRs\r\nTjo9FCAsYFKnokGXEHYmFG3AaMORld861cTCQtZ7nHGypBUsuhUznaHDJv9d\r\naef0TwDTP7MipPTTqtXp0EnE1g7+mUikAV1lMH7re11HMzT8WYyJT/lSf1dK\r\nV+YiAjmtONl+rNGHp+/OqzFefcKnc+O6ihze040qMOchNR+2ziRDHcj+hIRp\r\nvcvJnsJfToHZJl1pGyHPJ6T6jTbwdmdIldd7hiQWiP4I5WRC6Xz2k4GxBxAW\r\nx8XKrDv6pYjUzLjkN3OmdouMze6kp95xr7CLvvXfrpHvC5C6/isqa/2OCmn3\r\nDNcag1T+ajfuOcCv0NkcxhJJ+5iUpeqRUwQ6dIAJRo1bfYGmUbJEEviaawP4\r\nQdGXVyqB3IpmD9MCLaf+fPtfBTlqgQGGhjY=\r\n=0iyT\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.10_1656384198611_0.5790772583170269"},"_hasShrinkwrap":false},"1.5.4-beta.11":{"name":"alispig-advanced-chat","version":"1.5.4-beta.11","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dfd4cf4a46643d920c55672ceee2ad6d9cd4d5cb","_id":"alispig-advanced-chat@1.5.4-beta.11","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-W0+YI925Wcm0md8qacEw3hr0aCxmc1Aw17sRCLXw+BS+GFcddtR57BhUEUMkKCrcfGYNj7qNXo9E8yRFZlbNsw==","shasum":"7edbadc24d11ad174faf669a8020ef5e416f5f0b","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.11.tgz","fileCount":17,"unpackedSize":22308516,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD4D3KIbqvHd8QLhLbaACoAs+lh2WjsfC3k6RK3wVkEBwIhAMPLDTqlPPev13ANfNOmKYETW/TG+qgUQm3krh03FB4P"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiunKmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrjGg/+ITFqj4RTabQ7aWG2zhc5rIcZfHRVj0m5IqhjsXYPauXy8Maf\r\nuxNiBKraXQPUk036tHUa8Egb1tWtDLHHw8aBktff30ZWcCr17NzYkzWrKWJe\r\nKLe6LSOYvOcOimWt2pQgeC5Vuc213yUYrx64ezl+qDUDP6DNZLGpUNo5aGtD\r\n2BTgTn0LktYBrT5ezxp9HXVie3IzmdgiJzhh55k78SMcjNMxvB9s90mTa/IG\r\nZ8f/TMN7kVt4Weh5o5F+wKJp3OT6Um0LyVesai9ICvLss3Zsyzfrf/Y9JXnN\r\nXzoMexlk2CWzEiR2+ZlJjcVv9PWisaQD9cTUFfnr9NzLMieXeOUowr7Opx7y\r\nYwZ9P1NPFolAyijeI2papw8VqwXSpmkri4lgjB4ODmETUNgPPtaf+wXBsu4w\r\nxRP0E1j3hLKPYEw7j6bjezmYk27Adaxnr6Pi22ePBKD5H94Wr/hi+Kkd5zI6\r\nvexPIO2C1L2Tkw76iXddi2dzSoe9hZV0HDy2DmVAm+9JgVHg/cb+i+spfeb0\r\nBcOmevwS1H9IM2pUfu/NK652SKjUj2W4Q63z1OzNd0WsTgp0Gbjb43Bwe9J6\r\nUCu8G35R6MlMK51w+Xp+MJTKdk/gLDfYYSeaKm7b2g6zCmWIKPoTPkOBYrkO\r\npCzseKClNxei8arIdkHAm2ovidNU/5ezikM=\r\n=5GFx\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.11_1656386214441_0.32139971249184063"},"_hasShrinkwrap":false},"1.5.4-beta.12":{"name":"alispig-advanced-chat","version":"1.5.4-beta.12","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dfd4cf4a46643d920c55672ceee2ad6d9cd4d5cb","_id":"alispig-advanced-chat@1.5.4-beta.12","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-RfE/QItetFMsboqoZZBEumZK5Y9KJY20xkUfleXxTmuvv5z2oQ6D2Fx7spsnB1wn+4xj7qWhoOpa/XTuRKp1GA==","shasum":"ef3cde21fc51b84720f232d37376a5cd519c6b07","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.12.tgz","fileCount":17,"unpackedSize":22310767,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEMCHyd2+CpGPB4+CSmlQyC+A5mqxZbeGCU/4OYpFJNQ3tQCIAoFueFg+sajDXV6vLPO1vshKNv4wTL5wlgba4vmU8NO"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiuoQOACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpmVw/+OUHEwayEswvvvOHJPf4bywsd9LazOH68QQME/CTfogJCvO7c\r\nsSpDhJdVynE0WfjypRX6PWHopXLZOD4ZxoIOtuYVlnxnQ7Tq1Zt7WjVCZ1Cy\r\nowCcs+eVMsK0WitWL0FE9dJe8S9cRLisvbeTTKAPY8Q3vYbgY1Zs+5/pC7We\r\n3/bnCYjQCso/blHITDeFhNuXLxmcs0WFPeTp9qRHVbtZj6mbkJMg3KJuSHpP\r\nQLRpn0TzYAfoDG045tnLFdGbr99nVS9PXZlyPFWwkUWBgAQx6hf+se4bLZpD\r\nPYSVc2SNBr0cpekMG9wwW2KFAyao5x0TYp99tOKhiNMW9VV4wksqOID4bDjN\r\n2ooKa+/UlA5BePVrCT1KdpTosTIBaNnD9Hz+PFFz99CMsJ6yJf7nbGyzg9z7\r\nVrTnqbC9ybG5/ABh1x/PtJvEulmFGp/hOc+tmTkqYi5FLHwJaW7Sy8aBBbat\r\nlz1Y9ZfhWY7SLveECZIz49eQyjEuTJRqTcm5O2BS89iGQkaLS+0AvgjVhTg8\r\nKJm19om+oyNuTS086qEbNB9Q5GwEEoIfx+u484LJtm6M8Qo6dztwEJ0A/e9t\r\nvbhgVIPNl+BT05ZLqxMPbk5YNNCnJmB6uDSAEQMGtx+j10UINqgZlu2h8ell\r\nmn6cSRYMBFcaMfl0+865u+lyy/1rtZkmLbw=\r\n=6/kC\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.12_1656390670162_0.7674108022372539"},"_hasShrinkwrap":false},"1.5.4-beta.13":{"name":"alispig-advanced-chat","version":"1.5.4-beta.13","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dfd4cf4a46643d920c55672ceee2ad6d9cd4d5cb","_id":"alispig-advanced-chat@1.5.4-beta.13","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-IkAgNV+pGLiwK/sk1Td3rzE2lL67LOROczARRAJyaIPSJsm+POBLy0kKrCkzlsfgEIU/8S9tH1XWJYA8Rco9cg==","shasum":"b36e4882d84b45e593f65578b64e0a30f9041d19","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.13.tgz","fileCount":17,"unpackedSize":22310495,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCKzKiyDOH5d+Z3L85d8CyFo+8oDzLsEgljWuX3U1CNEwIhAJRK04MGSBZbTbUWvYSiL7GDxm9iat2HpeQrf2PEgisn"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiupcjACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpncQ/+OEjEh/zP8WDLHcbZoNIhIUlEUJUAaIOFZS0Jl1rYOLydFv5U\r\nB0SQvGornWcwXOvogiSp56F09YVL2K/wVA+p29SjDw71MO94kl+fi/gJnujs\r\nQV9y6nnTEx9fYcOCcnvkx8Eu9cFYGeY6W4ggoBFk2sXgb5xgzZTLh+OI4Yyj\r\nDv3GW6iz8EzVdHljfL4AC/TBiJmjSAKn0wDX2+WSYmGNfMy4tJwqbiuIZJet\r\nnQYZ5wH0pWjDeUM/06C+H6CvhBc71RSUmAzmjDJ7fu4LuTe34JCG9JdOlyX8\r\nFdWXq67zG0h40xWc3kaNoFgZ1FdR3Tvo0Yw8ud7ENDxjOwUKcqCN9eS3GwbZ\r\nEHAXPYCyklUKhbDU+Z9yERo/RTFH4qcAvIime0xmhDXQPAF/Ovk0yw7iBsm+\r\n298OFf0pWpfvQ8qNxBlXBokD6kDPmR66dj09PUYLme4vAwiPOsUOJvh6H3HL\r\np8VbNnnqsYCcBJlt5cMrzWGeXi3aacKKRsAXPyQ6vXdU5r1UfgMvssZGBUun\r\nzdh705KJ9PEKH6m/BEbkgUQcKZfpgXk/lKAB4qz/jcI+EKf92/IuqwFnYVx9\r\ns077UnHyzYhIm+3jiKGpvtjqG1L3fKfKVYw8agIIgKHRomTwr/tnYamu6PTA\r\nLm/Wybet8gwqfl/2dU7cd9Tr/Kk/AU0F4nw=\r\n=kEQe\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.13_1656395555161_0.1811797593599438"},"_hasShrinkwrap":false},"1.5.4-beta.14":{"name":"alispig-advanced-chat","version":"1.5.4-beta.14","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dfd4cf4a46643d920c55672ceee2ad6d9cd4d5cb","_id":"alispig-advanced-chat@1.5.4-beta.14","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-56+V1gYDE1zQZU2JalAbHviafvyu6ckKjPIo7Zt98wbnSlzMBFjV4evfvhptFWMZu59//QWC3XKvDBK1ZOLJng==","shasum":"94a3b741cfdea85a0987fa4ef8407999cfeaa977","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.14.tgz","fileCount":17,"unpackedSize":22310241,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFw9i2Hd2g/GPw1SYr8K35yVsm8nO+Yc5QKQnxLDqjg/AiEAlxc5CG1DSvylpxK/d+a1JbS0hx6+3iIi25o1uyPf0lg="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiuqDKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmot4w//clScyxkJl1j80lKKKNHbJfsmAShDxk3uwnXmv21VeOjKSVGp\r\nntQw7MKwlsEEyAeI9aukv7iG2mRv5B+V+Hd4OHJ8shQutSKUxpiIe/Q/83Ck\r\n1BmjI0GmpnF0yasp3Bf+1ocWtIWeHZApNwjPRMEeC6H4u5yjA0k/BIWbSOSv\r\nSi+9gag25hH4O1zzIA4iefZKE4ERyH4rgfdSr2UKC9X5wM4l5QPVNDEjVp/v\r\nb0ifj3VUpLV+I7HZlGw7aMdj8JffjPD2OQ5S7TCu40NA3uED7Fb44UQCso8a\r\nPWq4ml+Up2xkT2ud7axBa5K3jS2z12vmb6z9YvkNHI1KS/8P9aJ4mEmowMm4\r\nJ8Fgwbhawb2t6PlaCO9wb92jpRE6f8TSUNCICkaTVZwP/TnZGQxUHbaZBTDs\r\nrA4k1rLimJdDiPXqpJ6cLeHr01MwG/qFojVrh0uc4Bry0QpcUNsl44AlZjaj\r\nInhJrJgiG37q3+tmpmXPk627PDzXAQu1DbdRhY12g420VwKC/UA5cM1uR/a9\r\nIDExjS4QNWb6TtFVgZit5RZW0xLVGmyZjvXPdzym1z02SkLnCkG+7FthA284\r\nciFnYDaMxkXqWqH5D9FbEjax3IoBV9olPgNmlfzaIHuwzC7y3wKQoIs/iOER\r\nbjOFDP02YpQVBqjCf6ViCvy5YbcD+S7hvEg=\r\n=4QXL\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.14_1656398025421_0.42160167484784794"},"_hasShrinkwrap":false},"1.5.4-beta.15":{"name":"alispig-advanced-chat","version":"1.5.4-beta.15","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dfd4cf4a46643d920c55672ceee2ad6d9cd4d5cb","_id":"alispig-advanced-chat@1.5.4-beta.15","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-+WaNS126pQymbHnvXMj5a04zdJ+8eysbovc5Oc1+DgPUoQlJ9YiHDHNTukQSmqNI11I4jB5cxBoBV4IFTYJTGA==","shasum":"21468f2478c7590d1746ea5eaef90f503054bc83","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.15.tgz","fileCount":17,"unpackedSize":22307891,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDn65mpJJruFk4+zH2MwbPwKUxGtPi9Ozbsqo7eNCpmjAIgZEzHqCtoN80IMBzGCxnEY+6mk3W3ftDfnzWEIzhZ09E="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiushCACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoNYQ//YZ4yxBNa6awDv+KRCGWj29nvbtsTp0+tV8BrRi+a0u38KDUG\r\nSvKZMbDrOKK24Bwgy/KhyD6wt9xEd5NRgINj4LJN0gXpBjygL0Q8lDUvcq9G\r\nCymu/5G8rvR5BNHcJgxv7I9NVGiv0F8+qGXEYYJ/VvqMyL1Shlq09tWXE/8B\r\nipHG1GZr+iENunZM7fsBO9uHwYfhVuwl/NFNIrljgv4QouO2JHOKT/oerGKz\r\npsIz8c8LN2/1qY7OGxOkCGnNJNCXZOTZDuJi3zpJx8VceCL3bzE7uoQ1NQb0\r\nQjY8GTTR9Sx1/1LaNoy/YzJBWbf4bfyBrMFGyHG+ZZgWLURMY7LWp53Oj0RK\r\n4QcVmwIejOaIkC83g1iBrbLQkfzl7oxGLKxIfxOwJyDueqYWkpNL02p4tGFH\r\nIBXKle2AgTOlAOD/IyevL0YyB3SLHqtfc+sESArKmCT30LJM5LuGvsiZazT7\r\nCkLkJSImXbn3VYxe178LCjjzml5W9IjSKi3SGwhTxDmwjPILhPJLdT9wUucQ\r\nYrCG1XOMGuW8OMAffX0MsWbCzJIvmcLAgL2MgIF3I4qrXRfWFSQ9koSMZe3p\r\nwUH0a8EIyYS+W/1SN5oJVulT/bLc/t9WxFYtGwVgFbNsfaMYroO8nTdIz4l3\r\nEx/yB/Lsm6yF/t9y6I/N8EZXGomAstgWmgI=\r\n=j/Fl\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.15_1656408130388_0.2764146734771442"},"_hasShrinkwrap":false},"1.5.4-beta.16":{"name":"alispig-advanced-chat","version":"1.5.4-beta.16","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"40de7223f44c9ca09cafde6f909bc458c7a1bc8b","_id":"alispig-advanced-chat@1.5.4-beta.16","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-DU+sFfw61sMfsA7ePsiwnJM1kmnajEL8i87J48OjT7hycoXm6LhqiHs1qeSn1LHmx2Peos1Tsg/UKCwgAkM/CA==","shasum":"63f6ac996dc2257482f2f019223bd9b021b4a3fa","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.16.tgz","fileCount":17,"unpackedSize":22308336,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAaCfuNmXBHHEm00ObXjP2qRPzrC0Y0HD+MRfwvuUdlPAiEAoo8JhSPgz/QlfPpq63YmnjAFCBmzBHiNyLjO7dNIdqU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiuxYWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpRfQ/+Npz3YhkDAZduWYt6Vhpr/IlX+DlzqvHIlYcvfSB1JstSkIlc\r\n3w3NbgA1JpBMhI7HFn6J/g7jkym1rCJpdEaXrDqUvamO7QMRE9AQHlWH9GAI\r\nswR9rQxfJnmY5e9WNUMsXMXtTazGr+czcwC40cSfAm48RllZzQ3a5GH+qRBc\r\nCMDxHFN2MaM374ADGYtRTYcjz050qBj/WLr3thk5tdQ4vQWD4dbqPozRkjUk\r\noAn+Ndb11LzifJaN2jyu58+J/q/KgWTCMffyWR05tAv9nPYuDTiIO0BIChr9\r\nkZfFnKN82QMyqsm3GAOpU0PLc76OgT+YNlcrGW0yZwVbYHyuXYNMuXAeY1QI\r\nvLdiW7IfF8DtRbKVbgq5XsVh2MxsZBHFAB693RCaqpDgbvhQxLeVKgAh1Fid\r\nMILOi8QM0A0yxjmC8r7Dghd4E15ip8+BiMdl5hrtabPDZRZDGX04hSVTb9UA\r\nSOkXKB+N4HnVzO0bIIpUfCelSOA6Eo5IqUOat8jtBn9I9OmeXWrYpy+Ego9a\r\nw3ZJxYcfSTu3aUNfiCOVXwi3Qn4clKyv+ardvor6sbWXMPSykcbKVMYZrEPm\r\nuKGhciySGv7B+ntAs2G1s/kq73oEy7Sjrq1kG8ROF4z5z0wyYEqmB6uDnZiO\r\nou4drdbCo3WTEemzti9SycBI5p4pzA5HH8E=\r\n=Iuyp\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.16_1656428054497_0.07534029852460811"},"_hasShrinkwrap":false},"1.5.4-beta.17":{"name":"alispig-advanced-chat","version":"1.5.4-beta.17","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"4b00d003d48bcca5a02ff92f644f965b1d40effd","_id":"alispig-advanced-chat@1.5.4-beta.17","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-xDCOnSkG+4gxu7FNpy+t4tahFm3Yhg3dvp4Mk59YlNXucWMesZpU6yB8YN+p84WUQvjPwzAM51KnUUh9g0P12g==","shasum":"9b40f666ceaa394be38ce1670d617de5e207f426","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.17.tgz","fileCount":17,"unpackedSize":22309147,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHOQ6YlJsYAM/qstXjU+dU1gskv9a+Y7YJHUbjmKaKiXAiBkIjTssKRzDn5Jy6uQwKpmpQv4ro2wMdyOydYz6LwJjA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiu6kZACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoczQ//c1bosUQieRsluXSOXZ8TtZTAX2ifUsd3C908Ri2jRfiXXPoP\r\nhzCX3Xex3+xHKv+lChbhSd5+anBKdsX+COixzM6n72kXqNBSVNVx/dkVd7UR\r\nusrZ5QgDrPeGIKoeIx93dvieE0+3QPJvUXhZ51GOg7jwgs2st72aSmJbQmT7\r\nnV7VJ8Bb2U5kpGHbVCLS8ajatcVJwFYygtgtN5+OBDqNSmJm6lX8lDUTRw3o\r\nx/Ope0xtFCCcFW6yI0j0J35esrLNeNLvrXMEbA3Be4Ex0hZP/DtB2fkgP+6S\r\n5M1BaHEqZGQI9IgTmzHsidBAeONeDQ3j9F2hGCA4ATKxIXxuKwsKPiVNTOcs\r\n/HDy1hkeh3/KIY0juEP86jSszWBNjMV0KcJigfWkDWLB0qSQW6tQeAKo6GNu\r\nora2YUIORFZLIYvVNbX2YjoYgnuMArhxtRV2zuubv13oxBaK/ivDH/M4pn4C\r\n7pJqm/wGIChK88BPrXXU25v8xBzkmOuZO1d19jG1GaBnGl6GKJ6fOzJRVx91\r\nTjdJxa4giWwloq314RJuhicOdVvq0bHzWbbpozGmkxYalnqhPcC2PL3cXmWg\r\nDU4FNoMMABqtestkUwv49vhAoGIaIuQLzjAb8mrfEgLp7HQzyKZ0ZkbO+W+d\r\nVrtf86dnxTmSCLKiizs/t3ttuy8FakbJgVo=\r\n=hjnv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.17_1656465688791_0.20817094817023696"},"_hasShrinkwrap":false},"1.5.4-beta.18":{"name":"alispig-advanced-chat","version":"1.5.4-beta.18","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"4b00d003d48bcca5a02ff92f644f965b1d40effd","_id":"alispig-advanced-chat@1.5.4-beta.18","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-0uHvKdt1QBbhbVpl58FXuY68CE3VarWxi3GsCh1/ATpXzALe2wXBNCFIiMyEbvdL32yTq5MgT16lKwYLEf/aPQ==","shasum":"8e78cfce5ee62a4276b991a20a7dae6f39dcd936","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.18.tgz","fileCount":17,"unpackedSize":22309147,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA0IWF4/mvmKVF4ikqIQsJBrg74DwfHOd4Jt8eg33vNZAiBriVfr3y27ta/VfOKfi4+I7pnnkvZehf1Nk+DrbQAr9Q=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiu7ZvACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq0wxAAlqs4s9ubLikBAIJSlIa1aehKPJ4Yj4aU4rkN6CRRnYfCQoml\r\ngt39WFLvD5TF0MwDf8g7EMxQc3QrFZT86Mx5HF8VEHvPprPYhQ+wnC+JZFjc\r\ntMvORE6w/EiOKHUPxXyP55Y3ZfCIXYRAdptpNZFd8rAx4ANrnvhN3fa9toPG\r\nCn2TPuAw0262zDRJIXKEpAo9PiYyWI5AIPVEbMm5XDBHLxC8DRO7r712dsXu\r\ntz7XWtP1CbR23hSLx8vE2u9ab2P1Bs+f7S1TUQf2aa7Y/agQTNPdBcM7DS7h\r\nIZygT8cwBK2vedveMAUreqE3iwHoiyxB6DGYg3OrYjZuJ+YVq4OTNhkYhG3O\r\nBXUm9UD22sN2qx0ZT4bHZHyG9hKOo4s4NqMTt5PEfRhQIbaMLhpDpezAWZs+\r\np3kS83p4OJCxCC8gRTaj8iDEXHZ52duAmniiBAE+P+HnouEXLWWWKR0Qyfj8\r\nmTTZU5UjvxewJbaUha9IRAdj8nOtihPFig/obMLGdrXKTT7tIk04qiQJHMNA\r\nB8DdreqbL3Ft9kfMHI/Tvp6TXb7BxOku1R28Oes7twUDJ+oMgQZnMys0Sfl2\r\niV6wcgyEm0KAgNaJ4OrKtoXWBil3atLhko+oVhAfw2PWOXlhXREIpUSgmMaW\r\n8GdaCuhb8xk79XGlmnEyVfk0pQ5dV7mt3J4=\r\n=tmKB\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.18_1656469102959_0.02266701328129006"},"_hasShrinkwrap":false},"1.5.4-beta.19":{"name":"alispig-advanced-chat","version":"1.5.4-beta.19","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"12cf4cac0b452275d0cf0bf8a4e5d4f1c121e42a","_id":"alispig-advanced-chat@1.5.4-beta.19","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-W2/vOaVs5yJzxcJy8tJQ8xa1VF3fYzEi8NV5HPOM0DQAPChEIz0MUc3Pqe1CTIgCHCleekZpBjdWa+U2aLKuWA==","shasum":"a8889960d0e7eab4feba83cb7c942150ab9f7935","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.19.tgz","fileCount":17,"unpackedSize":22023885,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDE0MnTNSJbKl11js5jjY3HSnMUWAr7znj61MOTwLv2rwIgHM/NHV73G8118fj/O1jIhmU8QGgWEs7HTIkf07LsOS0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiwujGACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrb4xAAjS/w68SkVfmsLlCmESievJ/kY524UCv/jVEL5BPccnhTcoof\r\nJmMSoiRdwELPozyRST85R5CqdcMjRaLr4zUcMTvaCbPgLc661infw27a3Pd2\r\ncAD84E4lpGzqL5Nd8vZw5McG5L4BBum1tgFIO02CV37Rxc+9QvKKYFWrDUDe\r\nN/85pzwfQRVoVNHRjw18WB5X6+3but0nI82hBaoVrHIf++K/gXZwbuHUY8Nt\r\n9cmPbTiD/pDQ9hVJKMQi0kXi2GmA1bz9pfJSpmD8L4wODVCOIuqWRky3lTkQ\r\nQeULn6CQKQ/pPI0xNp0SkGuAI1l0hBp/FqlY9k4kK2GENprkva5Mo+jdi6XE\r\nNCWSvuiCWi3KwRAYpT8lL8x9WDLtOtiO5lmb2ECKkewiCxtVVMSq4QyQB0LW\r\nBfqmFYKK76QS1I4gGhlBdXDpb7YsBFl5tj4FYNqrOe2JeZi1Aegmou9bopzu\r\nsALOtu5uzO0A1jEPxvpTQ7RQ6h+S5ifYOvThhDf+kBdr4WM3M/WBrhh3ESmW\r\nCWmTnsk4xRtzTcOgvhvM4oNzn/MJYwig7xaJ0ct1V9gewWaXi7Wp8RUNoxNH\r\nUgVFgvqeKcq5TvZBpQG1acsXEVXqGbzb7q+de2/YnoIjFdPiXSt4foeqA01q\r\nF6Btpfnxy2TxAc8dXaCVAX90e6EeztHelZY=\r\n=w67F\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.19_1656940742116_0.4186594529156398"},"_hasShrinkwrap":false},"1.5.4-beta.20":{"name":"alispig-advanced-chat","version":"1.5.4-beta.20","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","spark-md5":"^3.0.2","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"12cf4cac0b452275d0cf0bf8a4e5d4f1c121e42a","_id":"alispig-advanced-chat@1.5.4-beta.20","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-C1CbOb9Kv+s5k0Jmpb82d8cY29RE35KDOIVGNhZTQAlTV4leiMfmaItOZP3yw2xLxTyzEDOSjyq0zrzx+FPEVQ==","shasum":"1da8f3bc182549f875966733d5163e54d4ae0374","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.20.tgz","fileCount":17,"unpackedSize":22024221,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBSJXKiPlKZArUQB08Md/YySz4r7SQdaRE2QyX8xqqAJAiEAtvfl1/qs1bAVf6nVaV6Tmpc65WHKjVjbM2xGrxSWjMc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiwwRUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr3hQ/9Hqckg+llGp5JR1o3bKkZFWPrbdJPp1izoqO8bmruXy6Ri681\r\nCpigQHWFfBt1vQmb0jNOIBVgky8Jflaakire7mIbSdHX6KIIRO//luad4mtF\r\ngHiIR5eNDXn2sP5IC6/PhBKtVylN/b6fOYoXtm44lwdBsEbFi1+vWWGVye/J\r\n+SxI8xDeBLWMaVg95xtBHQYx91AzeMXfe1PXl8zt8Yt5so69dlckV7lzE4ed\r\nFBqS5kG3zj2OfP/GyfjKpLbFuapa/6G1h1j3FXc7zM4hFD+9ZZF04TZKUwSQ\r\njxCmjn8qKFLr5JGEXqjGJkN0i91gubkNKI83XJIh3jvtyGE61gS+Ws1R5Nfc\r\n/ZXQHeIqW5AHryOEa8y0PUJIPTzVrw9FYHyVoQX0nJQatDu5KjAxJhKR7HAm\r\nfP7qTbSFoVF2LERJKehigQyjs2Vk49MJ5qiP8NR7Zf7JNSg0NYB7qptpvdMv\r\n7E+2IB2ah+eEysBzV0YpvPld2D9sxC/qAZ0vSmQbvT1Mpb8eUMdsIIXeaj4K\r\n+UAS45bSSFRjs7vxyld31xVoECyJ790/fSihOh18eQyy14jG1Bp/31slZTyy\r\nbNOquwNErypVUxbTXv8n9frm7yfiax4FEQAFidmafAh9ca0SklHiOnopAabf\r\nZIGpXSamF3FeW/uYSsCp3HJNCJJQnVjctVI=\r\n=XaG7\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.20_1656947796621_0.16077763948921797"},"_hasShrinkwrap":false},"1.5.4-beta.21":{"name":"alispig-advanced-chat","version":"1.5.4-beta.21","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"bcc240aca5c6d784e4abacb7924663e47d2a5266","_id":"alispig-advanced-chat@1.5.4-beta.21","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-wuYsZZZdy39lrFg8TMRjLF91sAlezVLtBBpamb4llaGeJ7laqw7Gy9OrP4SJO+Ljuo1vciS3+66VCW86dRF6MA==","shasum":"a8fd65def640a91d90827119b957be0192c1bc5a","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.21.tgz","fileCount":17,"unpackedSize":22024683,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC70aAyiWjyzxNScBvKS2im2OGpzcfbVr2q3DnVpFMC9gIhAPiYkc7DYXQr3RK3+M1Ft8sAAO5eych4zhdGZtE29lKw"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJizER/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrFlg//SwF7kQ35E7J9CIeWSg3OPcQ19Jww1znD3FOvXf1Bador5Pmx\r\n3MS4GA9fXxHvhjpyBMeiV5eUW+4N/uKGesIzLAcymT0bfHjOeZS2wcwmxwB1\r\nR4DPo0IIxaE8+u6PSRidaribAkpEs957XyksmzMi+GYb6HvefN2lP+tal3hf\r\n9E2dupuMrNY4ra8V+DgbTaba3iTgKGa09tS/QQroRgA9i9uTYN11MNHtB/cW\r\ngs+79EfW7qIkMiBNxAH7nCENDub1WXPYfG7Yt0FL1F7CoC69qz+VGjhB6mo/\r\nSwI3S98l4FpB1OsZm2Mm99ezR7SL7BEFJslf1Aht8UWTT0dMXTq3G4WTvOdh\r\n+OCh64/elGDfuAaT40oscMHVLioHatVrvhJqiiwsKBJ1PjIf3fp6hnguNcdI\r\n38QAeb0MUJNFWChYVzGN1k6hc/F8Dq0Y6UyXKmmstQTWrumPafSaF1giE+t2\r\nhdL/eV/MK7cBtNg3DactNYg52YJ9z41CXWHDNSUHHGrPsKsbUza77a0L6qAJ\r\nNOY6KoSHEWqQ5KofLUpMWubwGJonqwQ573zgryk+2QlqIhQ8mCVRj24V4qPS\r\nwuRsDHKpyxrFf8UhQtFYz5OcO8agrxTtmmtXAWOCskHE8z0XSmY6256blxDO\r\n3t8nwbRe8kMFZbPKShaNKZ6SwN3uU69H7WU=\r\n=vmxZ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.21_1657554047199_0.35093900452225224"},"_hasShrinkwrap":false},"1.5.4-beta.22":{"name":"alispig-advanced-chat","version":"1.5.4-beta.22","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"d408a589b60e15000372341660adee31d165541c","_id":"alispig-advanced-chat@1.5.4-beta.22","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-H2lWbdmMzmSilcR1UBniHoPaHKix5FZfXG1iz9IcaKtVJuFlJ385wD4bZrQwl//LYazt4B4sy9bBYPJP+l2B/w==","shasum":"cdcbbd1af8fbc563dbc50e9ebc51921e7e322cfc","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.22.tgz","fileCount":17,"unpackedSize":22024683,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAjkqEWBzNLQeIgUBAvOgq0vzAQskk8HHKoPGssbb8kGAiABmJwfClSklC2/pgHPYs4r5rb3lmLskg/ueGgo1vsqVQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJizZ5/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrlUg/9HN4/hTaWiY3II3KqHp3egPds5pNH9IvOcWcHif1arcsxIneK\r\nCshhhHyBu8AqBXKrJ04JceEwec20dwsmByjIXdfyW1eb0VfgIUUkGeO5zigb\r\na/M7cvRsBdmImx9RU8OGEUhO5IGHpI6uW2TTdDiLwnH3HQ/crXCs0oGVVzhT\r\nFJO28bIP7n4wyLGRmWEkJb9g1JWBInvMcdCAM/gKbGXKhc1viede8HpVYI3m\r\nd4OCcwvlQfqGUjPLYtnCg+y7PzLHaXLd+H3LINhnOJGDNjcBd9u8XncZ+Vpl\r\nyHPTdICBBDas2oAGTrw5h74270rlwUe9sYJ+TuOSUcLKhHXm1mXWf3GnwHv7\r\nbXWtdJVAnIuW8BC5r5hLW9XgZ3Q92WEnNEjdbjKQio7lZeJ23rONFBLJZfcx\r\no7ZZEUyLvjRkSuc6ziqfwNwhvbu8AU2mYOoFOsrY2Pqkv12d7ApPc/QmzKGx\r\nWiBqDyYVvNKuu+M0hlIgnOEW9D1sSCp7HjmqvGVnwy7I5mIVZ05hRk87Aeiw\r\nBWVyIfvnzZKkxK4tJIe4W9dSEHv8VsjPI0xsh0PGaP5+yiK9RvQ45bi5Ogn/\r\nXPPWH997fijSIPdgFsqAyw0uBfJkRJ6MprnhabJ6H9sDl0HAZu7xxgVSGuGE\r\nLq/7onCGT7CVDLmagYKxXxIpYvHq084MFdg=\r\n=NcAf\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.22_1657642622690_0.20158840829468994"},"_hasShrinkwrap":false},"1.5.4-beta.23":{"name":"alispig-advanced-chat","version":"1.5.4-beta.23","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"d408a589b60e15000372341660adee31d165541c","_id":"alispig-advanced-chat@1.5.4-beta.23","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-bj/9/GQiQukXCudpInDd6jDVgT48iGnxjNxhrn4xuz1v+D4WPkpQZ2PJClPp8Kojpz3s8CnLzF+PZAIEx3AfQA==","shasum":"6607f8a2acd6fded9ea32bbd2f425033e25aa249","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.23.tgz","fileCount":17,"unpackedSize":22027668,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDKRdoGhPPjihpeLkDw38mwpEPh6W1OyZTpt/VlvFcyTAIgPVb8yzVHfQ+/9LdAVVh5nIOE+w+XJmQfyIuOE8tPj0o="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJizoKlACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqTqw/9ERAQOHrx+20ImxET8Bd6G1yCuFm/zenps7Y4DSyM6Kb40t8S\r\n/03zSXERh/MC/SzaDgIOgneSQj38yDV+ItoXRU6mY116+s09ODktYVk3jRRr\r\nA/1n6DOGSMhPqngyyn/iBH98LKA2mnmnxn9ZCA3sGOEso4apn/AQ5Rh8p1JG\r\ntRto4DLyb/44Zzh5S5TRPOdJmwOwpu3c/VsJhAAautf63o/S60b0BrkYijHX\r\ncttOYxTkAbK7tHqWHkAepGcIzjsTNCtCO574hYYWRusR4aSQTGuuJKR06zve\r\niLu4H1zRPZnvS8tGdIHreCU2n2dlsoeLev7sdgSv3Dv6vTGN5+kURlR9q2+A\r\nGLGhnwPChJHFIjHH9112I5hM9nmsKpjWSYCJw4M/rx0UJTi/HINADA1dSd/X\r\nBaUTnWWpL8CiLH6Go5AVBgJQSD9qN4BYov5mAjntuGQp1BQdjxdYCPzJCb5A\r\n30Wu/e77gXPf7SiT42D4t01C/ogej5LIRWW1qeURMMnSa8QVVZO0hUhiY7WH\r\npFYZ2/y42jDfk3iprKS2rQO51Jj6ZYy/o0cwrrmjERxA6JLi259QMvzB/TMs\r\nbTpQ0971ZZppyWKeKPU6H7eOc8/iTvhQgcbx1lG13GJFd0XnRLPHnJRhlE0q\r\nTbv22a3I69a3foOY4mD31jneL74HA+C+7U8=\r\n=AJLT\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.23_1657701028750_0.48338144724465226"},"_hasShrinkwrap":false},"1.5.4-beta.24":{"name":"alispig-advanced-chat","version":"1.5.4-beta.24","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"198a725013530883521f0fb6805c95bdb7bba5d7","_id":"alispig-advanced-chat@1.5.4-beta.24","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-qN0RnDRXSHr8qPYsHyEqXQ4NeZoiwYyv6Be5RRacGAJbe/3mlGqj/dQfyM0simcOPgCugFSPxQS+DdoASQtv5g==","shasum":"35ebc72355238e822d9447c4e1cff77e3c2bde41","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.24.tgz","fileCount":17,"unpackedSize":22027657,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICsONO14Z+8qrskt4RPsZhBVuhxroBOKdE7vObgt6pkqAiB4p8BixPeA/T4bzxV42GdP/HipeJoZG6NuCBjTgrGutA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJizp2RACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpJrA//Rzogh17NYonSKmJpbKsMiKbxCe99k3fNwjFvERCS/eVZEIVy\r\n6XWM1R+keGwT25c+jcJbheqAlpl6oEYXx5XyP9QJdsXn5hKhxdCBIP27kvKK\r\nHME3R4OhOgNuWCfs+7KGs8shh7TVoSQK54gDlkPPfRpbdIx7auyjr0UDhji6\r\nC6ZTWOzu9JlZpbbwK7Zdt2malLd8T2cjLhlOPQjDu4JgThSRnOCDacuHuKg2\r\n0h5kp63LgoFIgi1jK1I9DZpOT3XC2UOwE532BBPXyCJDVhQQt4OkFSgDEiva\r\nWlaCh1xpVOs1OI4rtesGvIv8AmS1L3U74BVV04bqK/RjFZKcOhd2vbw5wZxy\r\nfaD7y7UBzkejVgAkQp9nJIYIM02M2N6pUvaMAfSXoWWrmb/v5OSvVfDj2NFH\r\nozra7WsQ88Z5pTf/n1/yKaNBJXs7/ImcK4V0MKb2TM12bD3F2cHzOVtiTp92\r\nOia7zGGxxwMlZDHUwJh5Tu0grEy82Dzp7vxJE+W1kssNuaxaUvPz8c2n3PH7\r\nUJbuN8lI1obQiq0zkpVW53+zJZpOA4pEVysVbjQdo7pFyN6JKrd6TwiAVzPr\r\nDiF9/YA8kTvO4sGcMtxWPsGS5Kl6ekGfY/7xACQSPWIqmpSyGbzDsUut7Iy9\r\nxnf2Isnwkz0AjQnGfZ292uip3g8s2bMW2+Q=\r\n=O5BC\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.24_1657707921256_0.2051404855360679"},"_hasShrinkwrap":false},"1.5.4-beta.25":{"name":"alispig-advanced-chat","version":"1.5.4-beta.25","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"198a725013530883521f0fb6805c95bdb7bba5d7","_id":"alispig-advanced-chat@1.5.4-beta.25","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-OJ2Ak/4nd7TwLIbybhqF1Ome59Zai3wNpn6yebZbdbhLk2jDJBpSqcgsVLbZIAG/UWwD9c/Sc3HclvHeUYe0Ug==","shasum":"5f37ca87630cd31588abffb4a5ed6b9fbb195a8d","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.25.tgz","fileCount":17,"unpackedSize":22024762,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFVKDt+RQGBSD4flEn/ANbw1oXuCx9v39tZtOLm+SHtnAiB5uf4klHHAljNL8KEByqLJCN/rqnIygN49DZYc6MTi9Q=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi0Xk0ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpFhQ//WEGw0OMJ0KwcNYSiVcW1Wzp7nfhK+oeoj4P2r6riW2Lc3NaF\r\nu3wINY4YDoh4USLAphMUVzamnhegayHbJJ4xl1ZdJmkmatAQYBuARrmTTMej\r\nn5QPwmZEH1DylzVdrmyvWfar5NgihL3LEBmcbSm87yxCTGzY/I4NpFSn8zHL\r\ns6ZkVJgjZwAET+jB4Q7zF0aOLwxRok+R0LNfQoOs5b5mrHr4PIX0HPIB+ZEs\r\n4/5hU5DZ6XdmZR+TUR0OXgo22IPTeCEGljuUeNbI7TsZ17wwfX7h7ZQg77cK\r\noXIdzBEsXZKPQ8RQH2Efh+V083fDRcGUeZS6mr13ia9/jH7xfsGGKmd+jhh/\r\nxxnqRXro+FPjkxQxVQKbw/1cp9TYR4Go5V4TwBTeFlUt/lSr1rL27G0o+Epr\r\nj7vS4HT77S2yDIgMlB6ZNldPdyXYX9+IvU9mUjrFI6+COpPkx2A7F/LNI4cL\r\nfIkP8aw816vkb10Y26tw/s+lvEHa1Vb0Ov7nHZMSWdwYJ/0Swo6XikuCD7i9\r\newGy1icvOErBRZqKOhtAn/4yme5lN0dfvV/+f1quQLVw4cAa57dv1j5v3Er0\r\n6eRwwY+cIvALFv86OXYScKXPE+nMYVf6K4KRd3w1MlwYNiSQ5XW9QhPMshIX\r\nD/QiA07SKqH+Hk+PBM6uikelLiW/zchl9SM=\r\n=nZ3s\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.25_1657895219953_0.7034711213568647"},"_hasShrinkwrap":false},"1.5.4-beta.26":{"name":"alispig-advanced-chat","version":"1.5.4-beta.26","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"45f5d2340c7b759055ee4027c497e41b410b10ef","_id":"alispig-advanced-chat@1.5.4-beta.26","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-vGHKm6v6GBsQzWI3di8XbLUfHolsfwEP//tTAmoAup7ZqYoPOXcm52tbgar6VjbzMPAeftTGZxvQG8DAOpbOrg==","shasum":"82488228d90ff9b984cda0d4b9759d98f62492c4","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.26.tgz","fileCount":17,"unpackedSize":22026273,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICFUARLJxK9IMDzFl1ZNTyjiobUy7rfTRVbT8MCwJu3aAiEArtaHW5itiF5aypaYBMmC6YP1DFJw4H8jrEtVR36i2b0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi1QTNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr58g//dstFAQ+ay0RvKxF3MJJNv48Rdkl1EAx9E+rHWdoGI9bubzBZ\r\nTC9tlFaXXpF+GsBwZBw/+7A0qwzKtSKgSYUK8w0q/RPunw8RGT2jD1rbcnUB\r\nzudOcgsCFS3+1cugCBq5d6fWDteDE423ef9s9pj6mbrQiS3cGRPryDqRPodA\r\nTmRLSABBRmm6H+8zGeTEQlzgqtz7EN+QskLGdBfSIAIpu4W3FmhZy3nRUJVU\r\n1FKrOPD++tB+QBNbWrCn5kFMO31wmcPDeJTCeh96FqYd8p1WnIn10PnRJB6S\r\n0C3UeLNZiY83mBVbeBhfyzeTd0iSIpKNa+fivwG/nD4/DVTnw5Z1KpF5vm+F\r\nk8aEIliVy/1i5mK72DfrfJS8xCKW8OBJM17Fts4Tx/Y1l474q5mPbd0Hi1GH\r\nEYuj1XVBIE0cZkb/c3bDYVgrXXKHeHUDfC5U/1O0QNBqaa0h8KNcXqS+AGS0\r\nqutwhDocWjGvWm6wXQdYU1dJF6n2pnmKZZ4tWpCQQ8d8zw4MT04n5iRCkDJ7\r\nQ8T9TpUCsKBNKZoTEx8X9IZi7LmytIYu7QPwK8ET4fg0SGUdQj+a2c91AVW7\r\nsbJqI3378J42ofMamw3HIVTVOw9Dfm8nX0cSlIMok2D48xnKliZcSjFAodK4\r\nrAx9anBh80y5zQQpQYcu0lCsW9GWvRVFzEQ=\r\n=PC2V\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.26_1658127564880_0.908318361255676"},"_hasShrinkwrap":false},"1.5.4-beta.27":{"name":"alispig-advanced-chat","version":"1.5.4-beta.27","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"45f5d2340c7b759055ee4027c497e41b410b10ef","_id":"alispig-advanced-chat@1.5.4-beta.27","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-ck27l2UAKWQYwJUPqKNm3iEi2GLteeOcE1od2/nBjErf0uBo//c45HpOmQtqvR1O4O/CVmOcbRqKEaaYJgkOPA==","shasum":"008756952cae70cd9a5b5dc0e102ca957faf5095","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.27.tgz","fileCount":17,"unpackedSize":22024841,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEN0TSjW3wWF2gSuBeWCKiSZzpJgzSR405f45/oZNj+QAiAJT9Lq4GUH4pQuEOHUtUul4s95QUSet7bYZcO//J1dmg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi1QouACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqaZg//UB89gVkuDp+dI0QIJsoH5KSYK7zLFjl2bmTOyQhyqih6/iyA\r\nYMNRw4NLC2iTrwQXQscA7EzXG0IwPx/3PLqNIL3HOTFwJdlXVMY5dL9w+p4U\r\nJgvCAd2b1USggkdrOyoa3iiqsmebkio0r9PQoCbQDdhk5i2J1zQj8Cs6qDOd\r\nWp9jzAlh607lPbAV7QHv5MNuE3p1fGqbSpoP6ZQSs81T1/nISk/idsseCoAS\r\nomaH8BDL2tkYKE5jQFRPnh30mPK30jSuEQw3289C3Awt1FGO4NdvQRvJP35J\r\njbzjVWoOVrXwyR6KwS/8hXUPrdc4WpBX/t6hVQCu9J0J4DAeWntXQhBjl5ar\r\nHHyOTfPF84s/l/uPPjjgfmOo5ZZe4PrWKgQp/+ug9FjuWua1n7GkVjxQ0HWj\r\n+DysKDfxYGRYVXzH6cYbGwDh9fTGyO4eLd/pVN7nEwKjMxKBOJp0+v4B6NYZ\r\nnfFbR3X30itj18oByDP3KZkD9xViaASbMKWuqYAW21q0UsnC1Ue+JTALawVy\r\nL/KoJTG+H8mEuNHuncUAaBSgy4wLqtTbqt+Z4Jd5nqjgJkEeN7egUfs/ZhdG\r\n/zfOblf2yil/YLVeRlL1XmmVTbILUrMNlwLOqxhsi1K9u+AvUgQEBjMYcxlG\r\n6Kpbukw2wlySHIQkA0/CnqlbTxO17wjTUy8=\r\n=4k+F\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.27_1658128941445_0.7677493669217219"},"_hasShrinkwrap":false},"1.5.4-beta.28":{"name":"alispig-advanced-chat","version":"1.5.4-beta.28","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"45f5d2340c7b759055ee4027c497e41b410b10ef","_id":"alispig-advanced-chat@1.5.4-beta.28","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-V9jE5S7fVkQ/kxUrIYxB9cBRxpNeeUSPDAtoxmeJ3SxOib5HoCp600iJDxUO5y1mnmRrjfTv248Uk3LIrKYW6w==","shasum":"dd062cb243babb1b64334c4d129479565c744e97","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.28.tgz","fileCount":17,"unpackedSize":22025353,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC9NBJyK7hUU261Ft97vWqkQCzW4wzTMDMZPVhwqnDBPgIgMxmwNcZmOavsm5fv/GaZK2H24dcUmevgSyL6jjAGAmE="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi1QzqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrgUA//YQ/Qxwh7LUhHU08hst2w+8YGNlw5oADlgrsUgdwYdsg7Azqi\r\nhjRZDHFW4+/mkA0+mfVucnjx8lRCkYFKDoUGgleQ+NVtNjBKFP31voJ7qj4+\r\njGESeNLqiFqIwOMVKumFWkkgDAJJbqUJbLq7bTlNMgTlX7jkVqkJ1I8i/B31\r\nvlc2R0jl3lsxNzJ25dnZLb6Ufl5HpdmOOj4M8Nnf9XvRt+7q/ivU6eRpdwwH\r\nb49Hk2ACZoZf5Yyb4dSMN89lXY98TjF+BxWc887xmaX8gKzO19bYtC20lrMb\r\nSeSg59yM4vlgmQwrBj7s+OTvgNQg/XE2d+txgflJQ7UeqaeX6AVd3D+PWYbl\r\n6djg7vbsmz3SSO06L1rpIaDlYevKfdvbQkcZiGG8DTm/4YcqbSTWYv352ZhB\r\nnQ/f4d0tcF7lscpkQdpamilQiB6L2T3+jTjNOmJHi4/1V+AhdnLE46tm8wFt\r\nVtRWg7M3PwDVCWql3kL4ZsAkT20SmYi1V3HnMb7i8HhjbghR/E+lsT4KV9cn\r\n54XTUel2LIloZs4kANp3feKh/QF2HtBPVzMKvadVQMW2ztsm5onGX2/R0KBZ\r\nJ5hwPxSCXOFZliYXMTS/ROdXsLLF3jxs3Aas7rmB7xZdyFaFSb9rFyReGIby\r\n3pIMgDMJ/mgvfRmigl54RmRcyi3M34syefE=\r\n=6AI+\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.28_1658129641849_0.027309429811855024"},"_hasShrinkwrap":false},"1.5.4-beta.29":{"name":"alispig-advanced-chat","version":"1.5.4-beta.29","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"90eed03ca782c24fe7eefdfb77eab0e7d2084295","_id":"alispig-advanced-chat@1.5.4-beta.29","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-K6oSM3YH2o4On3j8sX9jD0KxgoXBo0oFcSKXB3iJIsR7MfqLR0AsaHA1OHK7ziYi5+GqTSCsXc9lXFtGuwZl9A==","shasum":"59d992bcb98fbbfdcc3992088edbe121b566e9f4","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.4-beta.29.tgz","fileCount":17,"unpackedSize":22025353,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFsiLL0oBTy2m/D282SY2ji6SXGcca0B8Gnw+cjOh7Z0AiBXfyz/ke+gTymP4OTXPn1RUVUgpLJ1m5dBu6l/2dWAww=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2RAwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr+fg//UECdMs+1EUtG/qBYPdX/+BoiE1zbfQXyjdkJnI63Ff97c1eM\r\nflKd++gmB7YhS3ZUVGHXBkgE1WrzjyBz0/3KQLAhgHXO/V+VNcqr66dl3ukv\r\nhGT4NCsVbW/zK0W3hr3XXuKZsgaSvN/fEH+xAVlDiixpIsf9mOnx2fC7N7Gq\r\n6SBkoDKU3LSuPe35toI2GERR/FBmc1nmg0c+kqQ8qjpt1sD/Wu0IVyKuAA4J\r\nVVO035wbo1aVNoaDAN5fVJnCCvCitDvhOlz3NY0CpvWBVwBIcvH9fCJuScI/\r\nGDhckLmLZQarUSkDFKv7SvwDys55KG6Xm7JkdqN0u/6xweksCmn4jnwVSVvp\r\nC09f2MkB+dRWJWwWPu5BFxmjaV52OBd6FMKSrw9mOcCcsSynuM6mZl59lv8A\r\nNc41z/w6LAJMf4/oJ2vdOgmZ0kC45rX+Q7oJ+4KME4bPIgskxzQMtffSvI33\r\nBMltlQj+CG0LsDEShctjjqqJ76UosjiGvT2p7TOXIn/Ld1XtK9B0tzuogAyQ\r\nGSrwJGvfz3Tg6UUBn+IOQkZjhDcaZOT6aGtrIsdvc2i05N07FDojI075YGo4\r\naATg/sqUdjIXgqYRDdAQyUweOQnWj7bsQoTjCgDQY5u8G5lex7SyVsa+qKPr\r\n1AQ+jZx9i2MGMpuPxyTRjkHM6P/olnjKq0A=\r\n=DU5f\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.4-beta.29_1658392624111_0.3450868340171498"},"_hasShrinkwrap":false},"1.5.5-beta.1":{"name":"alispig-advanced-chat","version":"1.5.5-beta.1","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"a5f0fd0c4f8359cbacb41ec0f9af77f49a4bee8b","_id":"alispig-advanced-chat@1.5.5-beta.1","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-8r9CEwtEt4QiyAfUSSdIZB7+eRm5tRCPB2zFJ0/AndvnbBvLNG+W8mIFo033RhyZeqPEdEI1nHPZcVxzu1EbKw==","shasum":"6fe29f1f389c2fab781dcf41a0222a8b52ecb98e","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.5-beta.1.tgz","fileCount":17,"unpackedSize":22041145,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG5eDOAyCOJNa0Po0sv7y1p0h2F2taOJwRPwzYvYjby0AiEAm9GDghIXlceu59F5O2kNOqKBYHTIVSCy4L3FyEwJjYE="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi31vNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrqPw/+LCeWkCGvvVvO/jBPPeieoaciJFErN9zV/xwNikfnRwUHkdZO\r\nd2T/aLVBOX3ylUT4usSJiOZLIr9blsjVUAY4Hiq9e0KP2NieAj+PsBUfjs8X\r\nyDO8kVGE1sccldrR/zPKZRaKlwIRUApAlH3s1edGQKFHuofuIdBfvlSMlDJB\r\nqSxM55i+y9ijr8k7TvJHPKBHN5ZhBiEg8AM9T1YApcdzohwUsnv0Ud4khfsK\r\nXCTCwCR464ZW2bCXK+ngWuLCxRbiClZOrmqcNVQ/WaP/D6S11lMERayJZ9Ih\r\nlIuvIcV4It6Tu4awYLoc3zBoES546tWBHPg/RZacoGAB62+besLUQPuriXp4\r\nTHB4hGC94Q+xOSljPkDWFpFN1LqdHpOo7zXTSTvjK/Q5aq54NPlSw+nm8/Q2\r\ntA4HPmeLOlOwg7VbCyEi1u9ZOenb/UuKC8V/fnY5aRqSAi9yoE6k6Jgq5sJk\r\naJp2Tc0Ja4CyMi+SH92VuEbOOd96QopMOko8iPBwHpxjjYEnzNaCTo6Z52CF\r\nP2QGNYhZpWvn6bmXjPT5dCuUy/ZhJTEVVgfivxTDk2KMxImJasiBFA74Ge9a\r\nhJTlc/3UuZoYnG7QiYzOlF9piCk8eqNd4nHpJgyoQVchYuFO+w9G4o/q3a0e\r\nKIaSdzml9mg6yRs+Csg6GArBHONYaIZIl8A=\r\n=G7fV\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.5-beta.1_1658805196702_0.3064186882845388"},"_hasShrinkwrap":false},"1.5.5-beta.2":{"name":"alispig-advanced-chat","version":"1.5.5-beta.2","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"a5f0fd0c4f8359cbacb41ec0f9af77f49a4bee8b","_id":"alispig-advanced-chat@1.5.5-beta.2","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-G3QMOi51N2FPNrr6Q9wq/qk0+NLnHiEbRVRh1fcoAMReszKV2xmUilDiXTTrK0pfiyukjN8n7adgbAGANRFMUw==","shasum":"a0213463eae7a5d3867a162e162c8e469829f755","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.5-beta.2.tgz","fileCount":17,"unpackedSize":22049245,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFE9cWAfB+AyE1AlTaQQL4hFlAo6Y3k+iy14jT+WOG9LAiBH7edZkbj5f1YUMBJg5jGSdQip7EM/YS94ABXigy+fag=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi34Z2ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpaWQ//TJ5w95hverId8B9eZDiFT7XX9rFji7HsePL0V1KJQIHiMss6\r\ndaRnSEK4qjDUmjkyDBDtvt7MDvN8DnXkR+bzzY1D910p0JDGEwwCg0TWWPPm\r\nuvSfozrvYRFqKgvNDvMgLvSFHJXBNaEXPp/HVM7TzkvbQmhoWsQFqYLg/irq\r\nUBK9GQE9Bd2OLZlaP332ZkhuACQOItZdgZjrH2lafZ7N1iWY9ojUb5fWa9cM\r\n0f2lE/IrVVn78prg8TdxhItYZvlO1igy0+HofylgwBVHXD6u41VtRL2KkHH6\r\nFJKQkQNXytFu5Cnk4/lw4vf8/p9qEcCT2zNx7qN005bdtICf0ggLMd1qSA+j\r\nhndlwL6nuqjifwHsFviim2zAZ/9TmNJMxYpsMG3yq0efHIKBgZ6EOaliq2gQ\r\n01GGWg55CiNelA6e9rroKbloBLSi1n1nc5fZGYwuQTei2fZJZuUJ4JOHjbuf\r\nmGum+nrWRIN25TWc0lm7TcmsGvvW3HXI5W+4B6Uol7Q5A/Tf6zAJ/+82hznX\r\n16/hHjPR1KGSV2PhomJejSjbAk9KFHpfueHRxDNF5veifnaUpZmccSY1KEqC\r\ntZvNe3yagWvTU9O9OkcdVyXLl3tAvid6YSkj3IRgGepsqAgkXqTt+pofyjD4\r\nstSLWsaLCntoXRn0ciVjxBAyiiGJXELkmp8=\r\n=6Yam\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.5-beta.2_1658816118513_0.9999396596125785"},"_hasShrinkwrap":false},"1.5.5-beta.3":{"name":"alispig-advanced-chat","version":"1.5.5-beta.3","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.1-bate.8","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"e0814acccc1fb7e12104a910b7e562cd5893a7c7","_id":"alispig-advanced-chat@1.5.5-beta.3","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-ZmS7fCuHzD15sNE6/f4g4lO6Jm6oc4RcA5Fotrw4SypB7FKGyr+Pc0tgFXUOzApMorKTgZrUlXv0FK2THf5ESw==","shasum":"7c558f1b0b2c7921234ec9c8dc945b2a7229d9b9","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.5-beta.3.tgz","fileCount":17,"unpackedSize":22067616,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEjLBPKGgeZvHrTUdbNLarnpBI1zSaXQkrEsjy6+0AwYAiEAic9DCcnT/3xyEYukfLwOWpE3YMDEQr9c8hpojq8D5d4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi4JlmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmph9w/+K01UfS/8Ni+xjLmWABxPbYJYIkXwirkalkrS1k98Nm7E+JG8\r\n42GGBS+kep+imcXG3/lA2dTOapfOvj/DuWAOvcYg4VSCGSNebllrH4yxzgZ0\r\niUM6iE66YvfDFmlnOwQScmyc28D1vmMGvW0DzKLZ9O2Z8G88A5xsu5fcrX3H\r\nWjbVUjnp/1jWTdrsvyGkv7K6Q9thDkSyQe/xsiNj8DRrCZvZ2QJIwcPmpnMJ\r\ngyoFlSA61+No8M2iriebqrZFCBrYFOLuzYSHHYVa6DAp4ZjivGFYigoCBRNY\r\nr75QHPfg/jEnNectHQv8Cakprzymm3QxTjNcG3SX+HgxRjv/kVSnpQrMMS6G\r\nw02JkMUbSb75kyPXK1GwVFJVTCnv4mUHKEZY6HiwZoVJj5RZnldH1Vp1Y/wj\r\naP8y5JZKXJp9w13oDo4azEwqS4K2cXlcAH+Olvaka5y+ZLpLCKQmv8Gt0bI/\r\ngb9pv79M9unSwnEACq2X8bNG2iuGoqsT37xjth+mM01jnj9VpTdvqR7qZU8f\r\n3IWGFf80rtc7zOttLbEAfm95cTfaZNdzAiJ51d3IrzO77IZjvo134E5BQqMu\r\n60QYGDSu8kLxGzN7DzDGDH/xlbCmTHCJtViXUnScMCYm5p6C3fxOqgdfLO+o\r\nSZNHVn3C4n3WzFVousi21FWrDhtOOJtGWAg=\r\n=qP0P\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.5-beta.3_1658886501822_0.17228852157109587"},"_hasShrinkwrap":false},"1.5.5-beta.4":{"name":"alispig-advanced-chat","version":"1.5.5-beta.4","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"1e834a5ec6b237a57e7ccf76558695d5152bbdfd","_id":"alispig-advanced-chat@1.5.5-beta.4","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-/ZywVmZdFjNDRDx7o3sDsPUkWTNlushqI1fUCQujlY8NVyFKMJVnFx1A14PHrIP+bAhle/6l+wWMa2cZL41pdw==","shasum":"aa44e67d66ec8ae2e2bb59399a87bc264057e07f","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.5-beta.4.tgz","fileCount":17,"unpackedSize":22067610,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEdcuBN1TQrzrEYedY11VmgzISggRWtBUHY5CzdyRDwmAiEA56i4XGnh+hLQR4eUH9zVtX6Zqm2ttaGgudHo14j3P80="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi4V7DACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqHiQ//bSv+a5PeRzt9SgewLaFyg3nVuQJBQSa10yNamQpfhWWAwa+D\r\nDytxEBHMh7YWKtvIKvIvZn1A1pPuzIWiqwHwfu6JDTvmQuUjT/BwVgE5FdlA\r\nqlmZszP1s2Y048WUZD/f9aAqJjTZr3BI3etjPlEzVv4JiAX0kzZCOyxfh0wI\r\ntGy2fDJKngNs0JDW0SxEnbqC+VAEPjEM48Ystditnvhj3rKb3ehYdX3Xjhwh\r\n11qVsOfZOWTq54Z3UoSuDBRBGnW9Dg2tSoMrFdm6SdXK+fIoamxBWp68/XW7\r\nGgb5m9SSUEHKCtmyAeUXV9IydXGlxLYFvwBKIty6ApbNlW/kjGSEw6NLZnS1\r\n/n7SEjDfkJyte02oSHcq50cafgfuSMdkN2DRVPhwKLKRDrvvOAL2KVqgg6WN\r\nVQu0zLM5e3GexacbqO+9hq/tP5GRJVwZpIWwss/eoo1m5XiOtYqSPimjv1nr\r\n8eldQhcMdYATggK9CfrXjL9J+daDgTdWDC2/JGeqPcCSBCX/3xELNdD3m+0W\r\npbsKqkV/MqikoWMI/VmdeGv0c94bZfvwA3LO0++ZJSi9YtQnNid0JAeJE/1j\r\nGLk++uSqPkYR0UdKmWBsgX45m+6PZIyFV/IQCrupeb6KTPAKqsjHdhqrE9Au\r\ngaNTsFId6hCJmQrGiisOYsDJN6/fIz0FwZM=\r\n=QJrz\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.5-beta.4_1658937026464_0.11513395373770807"},"_hasShrinkwrap":false},"1.5.5-beta.5":{"name":"alispig-advanced-chat","version":"1.5.5-beta.5","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dd1ab52b82d75458ec519056f13efd980d6498de","_id":"alispig-advanced-chat@1.5.5-beta.5","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-4BoCe68143SYQ0zFgNTmp2yV4m8w9LvT3xjDjP4uhPxoFieruwqf/79QdiQRxw2M8Y99JitxhQDiI3PIOxhVdQ==","shasum":"b398dacd37f710ffa8ea96e6192716d7a1ed2434","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.5-beta.5.tgz","fileCount":17,"unpackedSize":22069895,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICs8b6706ch8l3EG1xVHeW7bxkeyd8CwlzUkQMmIjV7DAiA7TvT5Y5184O4lNjPeZFFBz2VWK40r06KcK0nufWPe6g=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi4eMUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpoew//U/NuPVBtKqW7Iw+00M5kyAHFDTgOXVw+0ruOYr/2bpWt50fS\r\n6g7Ld86TDZ664UFgb3I9wCzBUdcIJ5JftfOwSSfyTrb8eSIXyQ0ZGWlhCXPH\r\n9aIdJUI9tMo9aKy71DYbjWw2DG9plmSvTXGmnG4FfLHi1Hihj+KGw0Z5+PU5\r\npDENbKAhRVVcMvgAEG8tcooecC2CzxGIMx9LjYT4XSOzY0tvMnUF1X2wQeYl\r\njrpDKg9tDyYBwa/0+cavjTedS0mRVPX6iQFJRO+Hc6s8R9BxfV06XwuWtvTn\r\nJe7Z43R997CnHa7KhBzYzXITM0uMwMHCDBojfGNxSqGnzYJWaI3aioCiyjPA\r\nQj6fQzrE+26abQnquYN+ru2yHUUjTZxDQWbWGlYuASz5WXJYoRWZ+dybDzmm\r\nJ5/sl/IYwiIdLItMYQuPI1L3WZu/GLECRemnjYcnTQCV2XDFfEyL/jyPOvzi\r\ndXOoE639I2fSDF3qZuz2nvmaJxr2gVetPDcuxA1Bx51KFAxlbfOOO2jgqqj6\r\nTuO2XHgCuYYEPKLOeEUQM+xO0HybUPACz2X1d15SYz2Me1WepePAWUEApRTj\r\nxWwocfI0LJJagIoOXhjABvfxfbkyoVVi8VMZh1Q09RG9QTj1Pidg8+CwEEAG\r\nxLnGPJhpOieNaAK5DB/eJdfD1sMh9mqCYwQ=\r\n=97Wt\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.5-beta.5_1658970899933_0.4324761333545557"},"_hasShrinkwrap":false},"1.5.5-beta.6":{"name":"alispig-advanced-chat","version":"1.5.5-beta.6","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"8e12b8534120425b41f0bf44e0f1b9d952f634b3","_id":"alispig-advanced-chat@1.5.5-beta.6","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-1wUAGh7ZjRau2/3EHo4yN1oR/bs6LNbJx2SPeGY+7L7PjHFcmzRpJwW1CsXsghwtskbmKW0O5lVi9nEsMcvCpw==","shasum":"6960479b3fdecc27d572609160a54ac5fd304487","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.5-beta.6.tgz","fileCount":17,"unpackedSize":22069998,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDa32xqCTScCnaD/ewViU7C4JnfQ0TCLYtiZVIESHFc0AIgdOtYYoTAkFsxhjgReGZjJiiN8bXaDTWw7++MTl2piT8="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi4gg4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmryVQ//STHfIDJzn0be4qIt8/V9D6OaD1hZSe/N7lswB9po10b8SfDh\r\nihw2ezaXBbqj85aq+xLnqUft0Nd2I0jY15G9LA3DeoZAQNAbJUbKPwNiYHXV\r\nRPKaeDUwyfqU+fwSSdn3Tue0kjYZi1fM4y3fFaitBrbfz5tJd8mLukIKzW+K\r\njmA/SBPijoua2Ih0VtQqVWsaNAHcFL+mEWG/QPoHKSmTcaVE1NwJ51b0YQbm\r\nau+zEXRboQ1frcNuc9kg9C6TtCwiJZm3h1YSStbGbVC+sPGgLlUSCGQLWlkn\r\n1UfNS/AhsEBbqBz2TW8KS/mFiOHtj1tLqjdPhsr+ATXy248mNgkeThxkCfFp\r\n055fLXM1X/cFz5sQGRvLQ35TQ4K4DzhJqs8c/f2uWF/5K6uBsiV0CfpfE51h\r\nAABBDWwLqCUwbAZm0hkzTeYEV/kiQ6h7PWbiy2I88CRuvUhOg9j5rSAyDIWs\r\nekHrY3KBPf1mUEtXSAUy4fOc7IaocWAMtY+SH98de1bpxU/w8jDH3T4uoVru\r\naiXLU0Dlw2HKPPmIIndvkHi4w+n6ZibMtYqF3hrCogKlHM8Yr2Jv4Jk+1Vuw\r\n4Yg06q8cDU4FrDG5cuhlaGieYspGjmeiKJMSXmMkf2VkDGUa6b6HX9oOncI/\r\n4zPOSnE89JZR30ry1sKlPFYlaU4fQ+bHK24=\r\n=HMDU\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.5-beta.6_1658980408260_0.6355178035357503"},"_hasShrinkwrap":false},"1.5.5-beta.7":{"name":"alispig-advanced-chat","version":"1.5.5-beta.7","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"8e12b8534120425b41f0bf44e0f1b9d952f634b3","_id":"alispig-advanced-chat@1.5.5-beta.7","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-Nn6L2mcmST9kj+CoxolPbT3kX5VnWnFwnpSbZBts3sDH5L8ZGCvgbjfV1LHkob/6h9AvoB782D22JC4P1cHHvA==","shasum":"e5d055938ecccfc1816a947a070862237633ad2a","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.5-beta.7.tgz","fileCount":17,"unpackedSize":22074679,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIET3dcSN/X/yxnNeZC2/6u9gSyTXTMlOb2WX9ss6qRBRAiA8o5ym/QtNZAMqk8E/m2+D8MPYPwkExDP5SQ2E1etQuA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi4glsACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpexg/+KoEE4CVsrvjl9D1JBar2q6yAALO8PPijpkrlphjnvz3vBC0X\r\n4WGdpmUlKZZF8yu37tWX827XEYlrjrqEDqJQR3TnLZMhvHvyDkB+2Fod99Oz\r\nCK2cv75PotJrlAVO9A5nRqTWNxOojSalvs9NU1iRwyPtTuOZZRZ8s9OXsasM\r\nu8IZw19vH8EYqBKH+2f/6MjQOlweEiId7SIk3fk5jAejj8444lWVDxPkf59P\r\ng8O/T6MvIiQhIG46GoGaE5bc3tsklUjEFO0ORMg2yIGtAxOzJBkjBufw5gbr\r\nknefwG38PUc8xCnIKRBZf4kkyswkYBul49LVSG4yl1ZZk8MR6MXidwS1ClM7\r\nm9oyUlSgiKJTr1VpyrYERElNqlKPLsJvNY/egVaUf3BBf/o6e/flOV7mH9yn\r\nNiqsPjm48BhQQk7FDFvwhNW2a6x2AbwavMzS3LwWC26JWHKTnh0SnDWU3OBl\r\nwmaAfIu/4N3t00zbjgjoWQQqmQgh+Xt08Qmj9KBdP2G43u9jt/ff+ePfhWN7\r\nksuaCyTMWKzvR/H1t4yQ5tHS/SImC1HfOPvLMRX2cEpgAq8jZW5+6lWkChGc\r\n9kAU0qrb1OufVvIKIxkPIbYwT7ww4MlK2piwbIaI38UMhxO3kNgD4atPEu15\r\nqJ61wWqbnsA8e93N0mE2xYB9CNPCPcba/YU=\r\n=lPjr\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.5-beta.7_1658980715685_0.7521670941072001"},"_hasShrinkwrap":false},"1.5.5-beta.8":{"name":"alispig-advanced-chat","version":"1.5.5-beta.8","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"4e0ebcc7e27d0e2b02531ef86038a397527a6242","_id":"alispig-advanced-chat@1.5.5-beta.8","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-qGzip8QqWg7YszLxBSU/K30BHhsJoSdc0pJhz7piw5qzezsU000R6OmJhf/5cC7wTKdBjyUdEy+ySKreXQGhXw==","shasum":"02093626880acecec12c4f726c0f09eca961cbc1","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.5-beta.8.tgz","fileCount":17,"unpackedSize":22074657,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCMlV53bTNH5YZsmTPty0II/b9IGrvHg4NpMfH17kgPWgIhAMOZCJHwHVhPt79bs27Z9uENSEBpw3s8PagZ3ApvaoEp"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi6PeGACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqfvBAAmMuYIsKG3BhQ70VLrZZyeonEE6fs6bKYvZwnaNLcs1UyZ81I\r\nNyA63rORNO/L33sTlG7SyZ7CTzFDQL8KWRjORvd53shrgwZCOK+A5Cel6Ss8\r\nmD099gV4nULnsovqEgfJhw9KMksJlzcpGjb11JRoZzgzy4xbGhzFlmrbQMQb\r\nQwb3FgvfRAwTARh9hpLkrWaZB2RVq5QXd0H1nkpIS6LtVooekaVWOyuiAjhX\r\nypCPvb8tu+3LSYV08mSlmGEvHGX8VOI0clwcQzFwWhH+XEGRFdbEVwJ7Zpqw\r\nnWYk2k3i81muP9JeFJVJZsn1g7C0FggW38kgv1599JRfAhAof7jtyG8RG5FY\r\nNFFwTTIGcjunU20Sv2Ls16ExcqlYn5DxhW73YBI567IEyBgb167ICvIhZco+\r\nG21xno0Je3kpJoun2mfVcJOZV90fnJz8Ce9buLdx3T4kJJq7cVbA1Izf26rT\r\nt1RaOtLThZJIRiJ8MO+gjEgubrMFUSccYQIJVPOcpY4xC9TOO6HUDz91Op8c\r\n2r40/7Tmqv9YP/NqO+Y4rhdoZKDQAlTtDd1T1VibfJ8EG6lYLwaWiIoW5hvV\r\nafvFMXxD+eB/LEu4cVj2cbeHMhad5S4hg+PpDwFTY6utJxBbc2NcnCcL4rhT\r\n7GeEYmcsD0bZ2FXY2DykzeGID4X60Yz2f00=\r\n=wSIF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.5-beta.8_1659434885925_0.03175146857995137"},"_hasShrinkwrap":false},"1.5.5-beta.9":{"name":"alispig-advanced-chat","version":"1.5.5-beta.9","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"4e0ebcc7e27d0e2b02531ef86038a397527a6242","_id":"alispig-advanced-chat@1.5.5-beta.9","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-lpnrOBxxFUt4dW96LysOQDfT8rM42XoWTkpgYqUCKwhGxQvig/zcv6jwmYqHzCMGoUwWp0BuKmL0GXDgNgHhWw==","shasum":"b8b86e1384b5c411b46bad2051f15bbaab0aefd6","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.5-beta.9.tgz","fileCount":17,"unpackedSize":22078813,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID9XXfSKmes4TixO+i8c4RUc9Krn+Q0xwzdjFU82s61AAiBWFp4je5qGuFOJC+8YhQKJpqWQQg9kuPiAF8tW44KGQg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi6QDzACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqPxxAAgpfR6pGLdkWlkVlFpA6sEpI3HItug6JQJ2izJFDVTH/UEtAJ\r\nVgtZqOVvKCcDfIT16AFesu88EtGMeLVnZZh9x3E1mDDjuBx4hSraSMuSZR5G\r\nqc3kgl3cadhdGYXRuLNcKja9lwfKS/7lSLQF1hQH/qc13OwJVk8g7W16DCV2\r\nrf6Of9260Cn2GU9xqYMU/EDTKtZ/2SWoT5i0WDlLlFBk7PAG/PwNc/kJMjDt\r\nV3VHrUVY4RepjpgF/3ep7uIpWQrsQ6sg9zwCNjnGP3/5v9pihmsb4Sbt1T0S\r\nKTEs+D1Q0pS2Moa/w/4B7TOTtT4yvvq+uZloEgDTDspP6jj8VG5sqmc0g7An\r\nqZ5hYWdWppxqkiH1ImntxaWiobODFS4viufFvKg/nan00hQpbTaYwf0DIZgA\r\nVT+s1R2+lnXbMfRnBNdqAHpmn1ZKBgLfcq9tKhFHY0biaXuH9ipYH/NCjW2o\r\nE+e7cSbFcXhYhji5PMBKGB2bv2A2CZvxvNB15QD7ufefcVrU8UDKXXsQ2sUC\r\nOrMdCMz2IPiTs0iEnZtARkTjftxARmQW/FEYZ/TzZJKsEkm/g92oLmYAJCYy\r\nDxNnqS3cwpc6a7tyGcKLc1ihsxlCfnhqAiT2paZTuSGtGj1r/uerCKWfGg+L\r\nnG0zSuB/CyerRFl0a/MVgYemO41rxB8xPVo=\r\n=GWYF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.5-beta.9_1659437299334_0.5029509284939178"},"_hasShrinkwrap":false},"1.5.5-beta.10":{"name":"alispig-advanced-chat","version":"1.5.5-beta.10","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"4e0ebcc7e27d0e2b02531ef86038a397527a6242","_id":"alispig-advanced-chat@1.5.5-beta.10","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-37ETq5rUnrgVCbiMZcIKwH5sveZxpCN9L3VdGLq/w0wj75A64uWn2ILvXEV0arhbT/5mkRWMgJsD5FughybSEg==","shasum":"3eaa29fd7d072f129dc2e029463690da0b236920","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.5-beta.10.tgz","fileCount":17,"unpackedSize":22074680,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICxOlfSdXHDShYlXgIZ05NJv5EGwKzY0y/5JR6imhr8EAiEAhRDnKGxVI1VnTXsYw/BY6L8Zw5ieZKZ6liLseByxbic="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi6QOHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr/YQ//UGRAggpzRJhuTLav6V/6oFyBR7ceuZlT+I7AMzbx98arktLD\r\njBfLUQRXDUSOi0HfeVfZl81428VIFeMAC8Syb36TFboEnN+sYL+KiCZ896Y2\r\ntkYHseHTFhL41Dy1Ft6knwSd6DQobRoj+Y/M1JZJcRj/0x6QbwRmcBrY6WQV\r\nv4DU6KFRIqBOGKj3Y8DvrChiZN4Otji+E8kVBagRxHGuXhTlX0NjaErywiba\r\n3bKyyVaWc2HxToF0mYTfMEDkJNOr0Gkv0GqntX+MGtf52FhxMFYdCe7Wx/CD\r\nZ7YoUxDy9bCdVgO6zlDMmJifhIdnuYSnJXaurSLwd2/3/EkGut20q/75p56w\r\n9aJB7jAhlaDpfreobzHM0S/S2sVFNuWuDi7G0EuBZlu8NtY6bYkXFkXJUDs6\r\nIKFI4XY2mgRh71p9I+/HjX5aKLf+uk0YUpyjgETD5aoMTvoSX8dX9hNfySb4\r\n5B8NrPseET5cjOVmjwEymxqJNLEii+Cna2ckTCtFxxhh8bR+R5q0Wg7CDQwX\r\nAjEYbm6p+BOrbCSaZyumr2E9pkZb9kkw1ulic4CZsDz61rFCoNOVVI1ARM0m\r\nM2Xw+j0loLW8yYCASg4RW5UzoAio0TjcKd/OCc2wq1QvyDR3vZHQjPafXozM\r\no47VfGIE7aK91XT32VL2nGj+NOVH6/I3Ebs=\r\n=0gpO\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.5-beta.10_1659437959214_0.3311346695046493"},"_hasShrinkwrap":false},"1.5.5-beta.11":{"name":"alispig-advanced-chat","version":"1.5.5-beta.11","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"5b607d85df9eaa3ad9036f81853ead941ccb23d8","_id":"alispig-advanced-chat@1.5.5-beta.11","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-X2xX73Mg39s/j9+xrG5u7EpI+x4fu+V0/5A5b2UBR4JqaBf2PfCP6VOf35NjkEdoZz3mOnmafSuktV9IPMF/3Q==","shasum":"93f64883667639a514411018c0adcb0047d6a9de","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.5-beta.11.tgz","fileCount":17,"unpackedSize":22083106,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBfK5dOJNE9/7HjPXrTnOqP/amPDhIHbwngJKhcXhRbHAiEA4vHuzLKkV+rWTMyoBnU1W3x33AOCe6oo/A35Af+SWAw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi6lCWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoEfQ//cLGiqDXAfW14Rqsn3On/BXQjVagtVEUNSOVPceuBD9DPPR1m\r\nZCTarj/pKev1nwH7QeeQyC+Q4tIZq43U8fcEvvKe8Oh74puTG5vG0+Wggh2U\r\n/2ygVyOf+mvKVpnuvMJUmTWBEcm997c7dvGZ2Oth749H+wsgLDZeYklybifl\r\nskECO7854zgKZTdAr4A4VBUkbuudKDnnsL6hNWsKooKYbLdXk+EQiKErHMvi\r\nlYhcAzQTzrjlRRwT4E9ugPxg1ADwQd0sZ9LMLVkJKgphR5ao6kvsHCndindO\r\nSjZxFii35xqaFVg7md5rvkFrubze18WkDCIimD4zkYVU6hNWBqCrPnqIhsoK\r\nTAzxj4JAgK+GRCWIxLzqqsMUXfa/XxpIjIYNyuwomxj3lTHoI6hSgx/0emTO\r\nWp8ib/gxDrlkJk0DmynL/bW4/B9pPAygRmvbQYiw6NDkdGZkwFHTBsnHSwuo\r\nFc5d9C9cNMrrrntetrS306/jLc31XaRo6MrOqcWo5IRhaagxyDXNwU4C6wvb\r\ntOURfz3WkuBnMvc4J18+/RyqYnZn0GmLkilIqeol6rEeKkSeScvqVTdcZClj\r\nvqj89C2NFRRsJaWwC/FzZcaT3NKvtqxWeYPx07xaKLjQ9dl8WIlHFx9poORS\r\nZSJQWBzNojsquYDSsllgu2rU1pq1V0IZArY=\r\n=g7P6\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.5-beta.11_1659523222287_0.9296093184364829"},"_hasShrinkwrap":false},"1.5.6":{"name":"alispig-advanced-chat","version":"1.5.6","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dc146e62a300e8b3f4d8c6df0175e1c6e38372b1","_id":"alispig-advanced-chat@1.5.6","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-BvajoPYn+wxouVZLfIzM0SpSYkBLAGsGV8YFOfdaeTSNMjjBrfgYW5HIp6shFY8OA8VT10SOJQqzMtjCN+bQWw==","shasum":"71748f4410aa06a9ec6143541b34fab734dcc406","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6.tgz","fileCount":17,"unpackedSize":22083700,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCW1ozM86ZHQaY7eJx8A/yLaVlcCCF08GHL4MFqV9+1WQIgGEdgnQoyo//ao9Mya0mROKoEY3e3CmHIkafUmD1dMR4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi7UHjACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqL0hAAmP2zWUjfqnbZcvxw6Pm2xDN17B/Qo+yI8AlRHywLxuy8V7cA\r\njGH3qeARRvOoxH5RGH8dZcxXtNCwAUV6/yUyTI3jTCJmul23dK6LECf8S1Uk\r\ntvOnr0kX4WjglYETiAqtQeo3vPHOAn1Jef1EGmwg7gQmmh5Fvk1UKIHjx6rw\r\nt5SFCNzWWe0glnV0bBZuZOiIFw/9xW9y2f3BSahp28Kwtdroq206P+11hnQ1\r\nDWVm6vz3dtYsDCPYc6oEaPJfDNXTdgDezY0IPc+WvzgQ5M49gQMiioUGTj/T\r\nYcRPIMbLd0BkspRLYLVlUlm2UIFmWRaoYwjxRzDqiNgKPCW08LqWRV4rfGM0\r\nAfyq2e//dt3qVMpzZkJePKd7zo8p2CDBp33BUaGcYTp5Hj9tpDtR81rcN7zb\r\nseKyngQ3lhqtTb9RyySBNRKUCa6zekhjDHWNAdSeS+4nKQGnW9d975T8Z3IZ\r\nE7L7z6Kld+06YQ5NXZWRFE0FJ0zVUDdLaCXJmzVfeYD1RKXWDn6kGl7rJNka\r\nuELTtb2XyRq5Rh10bNp0DrCCEffBOlqoWhLzZVx8kRNctGS3XkJbPc1Ch+jJ\r\n8g64141+QYwGKeJdj4nBwLHM/ORoejM4ebhPmpr716fCzg5PjyuBC1J9Txz+\r\n0JSQyks3wWvIMgf2ZxXrYgSHF0DCkFHGs7o=\r\n=O5+P\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6_1659716067342_0.4998735727410226"},"_hasShrinkwrap":false},"1.5.6-bate.0":{"name":"alispig-advanced-chat","version":"1.5.6-bate.0","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dc146e62a300e8b3f4d8c6df0175e1c6e38372b1","_id":"alispig-advanced-chat@1.5.6-bate.0","_nodeVersion":"16.16.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-qxG5zqrS+YwNi1GCe7rdNqM2XnmiXq6Ozt3DhSSfuvj2brGMIgyWgVIIO+2c/ZMPY/0GLfw2Gm+rf7L9Z7/H6A==","shasum":"35f4fdece62f379104671913ed9b7935d170a678","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.0.tgz","fileCount":17,"unpackedSize":22084308,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDqZ4pryjF5dN8zdEwq4XDLqMRYcEe3k1r0jCK9qqp8cAiEA2n+6kYBGCo14Apby51IS/k2UdAnofy5LkSn9nEF17h8="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi8+NYACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpdyg/9HtXVH94NfEZ6lvwgVgruY9/zcYqaR10dBjBhjQNK0DI1gJ6c\r\nylkbcecbdDWBFYh6Ib0xBjEG4vg1D4R7Bd8J1jDS+ItwIK6NFmgyqLbAZflQ\r\nE14ujR2BRJWmMfsRxewLdcf5E0MYIPUHNmbJeUeyrx1beaEJT6bUjj/aJI/+\r\n3HcCDjLkhjuccso/qkHPmdIZfzfWK62OspK9MWK6m7toBBvY7pY+xTuk2mHz\r\npJKVb1hA7h4RbwPwjLQnB1lCnTltKB7Z/8cf7KPQyNbERoEE0QeHBRiCEop4\r\nsACNTRYZ+S0KPovLnWKM//N+eplptAibP6QG3KUyo2lqXlDiajEIIWc3HzWb\r\nd4Lc3EVaGmq8R9QAgWa+KWnfVxJ/f4gPcKGtraZJF0vs2KVv2IXruRdCIIbm\r\n635Le5SINurQZU8WHsQ5UE5SIocIaT5SzCQ4ZdouQf2YO21OUuiOZD3S9g2R\r\nnrsq/tr+Yi26WdC+E8nRy8KyZ7tCizKXTL1yOpgAUm2gQ8sf5oTEEf01VeBa\r\nc6tQx7sW8efe8SmybZ32YF10L1ox+b/9JXeGRkGD7dJknPpIV6oKDKp3vt3G\r\nohXeFOurF6CVi1MtyCZyipoedoEKRO1h8eQmV7xGYBWINyGsQGzNgXPehOmv\r\nMuVlNIG9G+byrsKqVK6AIQ6xUKtHdYYgZLo=\r\n=SA6k\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.0_1660150615886_0.6381091083538672"},"_hasShrinkwrap":false},"1.5.6-bate.1":{"name":"alispig-advanced-chat","version":"1.5.6-bate.1","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"dc146e62a300e8b3f4d8c6df0175e1c6e38372b1","_id":"alispig-advanced-chat@1.5.6-bate.1","_nodeVersion":"16.16.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-+WOri1f4cZ00O6v9KsWuR5g6HqPGGhkK4gDwTQ2VUQZ2S/U+OICMEFJLjd0TSKnKG/p+nx19Sd9HE+QgkHfqlQ==","shasum":"9d0b64453410c72e1ceeb9057567a6891cebfc61","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.1.tgz","fileCount":17,"unpackedSize":22084308,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDml8kqk2NdB46+ZeA2e+qyCoCO2EHiDCvLCMSiXu9LKQIhAOcBf1Z8PmZqDHRhgZZJ+DaKKDF5lmXI7GQ5aZuMr3QP"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi8+kSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmotMBAAkjN+gTvKQ3owEwfsjLAOe5AzfPDfaddNYFoIPrc4BC+iSpO7\r\nHmjpGTShUOihgrPzM6p5uKGRVzXZLlGz2jbHwefA8Z7pH8F1z7iFPr8TlixU\r\nAkl7kI3IdaoyMAPmCnAbZV1KF1xPKsCG0glEDvevV03TD4UmIJnHjOG/Zlse\r\nOQNUA7jsl86TyfFzbIQuj3xtqWqR7wJDjxbS5ULdsQNLw1M/MfmC+fp/qIKY\r\n9oPBZE4Iy2lzxDuHviii5pkK/THkuh/r98zlQX/ulVm2oKBnLiMuxxI/OeeD\r\njcSBQBiT4S8TP6fcG3QRqo49pS+oCzCcWSO3UxpCJHZvtYVaKHVBszIRfZh6\r\nD5csYexHyuXV9h2wSGq2DK90QkSI4ySY779N5pONXpeU+1BnNlMLB2PuMAPR\r\nW8VF4O4gmGjJHsNd9WcR5nL/CsMHG7MN5KE89zBGRtrKiCAc2I0KZsw6MA7M\r\nPjSmh7bLo8v40mVT4bw/34Xfe6v2kcfJDg2dxGK2QWlRnrPWrDK5IsLk6G2n\r\nq/2Ycu//hns7xhIT4tvaBTZDiLeh+2FYLfFghWRvPbfONIAq6C//QL2M3Afj\r\ncWn9rhVYKE+K4pwbD2R6MecK+FIT10SXQNMAFyXPgQi8Eg9cyqxsdgtEW4lq\r\n5G4d2UCCu2POquQdSFTLUkfmNg6cV/x0lcU=\r\n=OUZF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.1_1660152082001_0.8320424444601346"},"_hasShrinkwrap":false},"1.5.6-bate.2":{"name":"alispig-advanced-chat","version":"1.5.6-bate.2","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"b03069d903a56b7a43b6afb9170a1543fe374938","_id":"alispig-advanced-chat@1.5.6-bate.2","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-Fyq2+qJvt5Nxi2ca6frH7Fl5UMB9cQVA3Wbdr80qSAdgg8y7ZBZg52Y96YGWYCFO3pDzlsexV/0n11HwYz1gFw==","shasum":"cef80ce23a24cdee07dac61af33e07541460d96f","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.2.tgz","fileCount":17,"unpackedSize":22093683,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD87BWCsjHkobUcVJZiLklMwfDl3TJHTFtGXW/kpv8kHwIgSh+CcPfdIFoUZzwm5TjPlNzEmlOJtmtV9Pr93Yx06/g="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi93dxACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmokcQ/+NC4Zk5CKqZ8Vxwm2+jLAG8N/2av8vq+h6HZuBN20My489DkJ\r\nM1XDh8zqgPwRJ9CJI8v3yuPINaDmk8XGXxdKzlsjAHUGlrHCyESEFR5QQNAR\r\ntoH8A48Hz7XIa436GzOUUh4DopfCybE2o06qZQQDvOrF/Y59OVo6BIrIbW0x\r\nmRKzGA4CUUWqzYkQUIBOZsenBTB0kSEOPQ7cuqAGqgelNaqamqbe2E9lWvQC\r\nG8HPudzRokOC4KEwMImc4CkI4ihsZ9CKrzdpd+jqZk5lneEjhWsgeVwhCF04\r\n4Dz1yHTt6g4G0A+oxkv4SEhQQOcBppyz7EffObX91P4Q/SZ5rLBoDBGVxSB+\r\n+TnCj5hLbxO2hbnbJDoT2Q23RDCQuh+fYUGN5zieeyin30peb8kElFxe76ec\r\n/6PJycOYH3BD5Y+sxqL7VbR/Ft2WGnrtanbNt6YOioT1pIAw/SMTwSSuTnkd\r\nIg5WQWrlTIcSHkUVKHg3odM5nGRr6woi332yyeiomPJY8Y++phhXji/pwxrV\r\n0BGCBdw8UB1Pai9PocPp2TlsLsTtGpIVAvoDwJLaOw8dia2mQnXYrcEHzPxe\r\nACjdNCkNZuN9AbHHZKzGhVHEolDrzai21pI4oRHwIFHiES9Znxj7lRuki+F1\r\nRZiqzSd5ViuBT0nm5qnggEu5IPLhPpA1rjM=\r\n=e/FD\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.2_1660385137186_0.6387586080375445"},"_hasShrinkwrap":false},"1.5.6-bate.3":{"name":"alispig-advanced-chat","version":"1.5.6-bate.3","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"b03069d903a56b7a43b6afb9170a1543fe374938","_id":"alispig-advanced-chat@1.5.6-bate.3","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-OMeCNcF0UZ1nLV1RXPMwShxDyjOlkTY5ozz+pVlusBfh/Rye/mNJWPwzruz8XdZpNSkox7dGoN6lT6lJbzKtNw==","shasum":"7540a99510d515cf2de3fffb1475b4a63b3f325d","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.3.tgz","fileCount":17,"unpackedSize":22093047,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD1TnZlh41N04ZYUphuERa3pRvBXyOOQnvOryewAnEDagIhAMSEUHtRwNDifU4pFUtBjsTCvqrLP5QM/KvjoGmGUlze"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi93ldACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqMQw//fXWdSVAANTo9tvbvv4HFlBlEogroy0eok6qz2jWNs4Gt/pUZ\r\nN0V5YaBazl2RCUFZgMALN6SEm9DzqQdYa73b9Ehj5OuysPXU3jt8E8nYwre7\r\nWBGkDb8Emu3aekx9r4e7gICUuEI1iiBg79dDqDS0zPDQ3L6F4w+NiEHu1SCm\r\nm2gFFrbaZfKFjloXvD0BnLbA82GwYGd0qBLkXGPm1928ARvyUlBXPiGeKLQm\r\nJocQKREaJc7M1QL4WzPc4za9PUUoVbOQVprgB/pyT/+bLfAHQhxG67k5aclh\r\nZlwFdcEOimDG4Q8qolJhJlynoeNUHvuyf9UiA8rVVput/fHqTiYhozN6x2V9\r\njLWJwz1SOUCqZ7x3BWKz16O3P4Maj5DkhxAnjRRzzxRsl0MdY/23VoFNPTMj\r\n358UnmdBoY+xZBGF4JA61AS+32abuywIkMpEi0oFpV7uh+mt89Cctf1l7Wfg\r\nz7uNwjASpjX3Tvfdhf/bGIrB1mWh4jaPkoQejZUl6oyZLz4iqvm2j17eic6v\r\ntfuSC1a6pB5AR3rvppovwSdnyKZrY3/9BW+xuxUzhxtLxttYc+9hcw9Mptgl\r\n8X+yr7QH8GLaOok+WkNRAWX/4vGK2OOf8w/jgf7NHL39q08pwUuyZncIWGdI\r\n2LezPE6X88G65qrt1i8wVTgF1650kcmYojU=\r\n=iWjR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.3_1660385629110_0.04834298330141307"},"_hasShrinkwrap":false},"1.5.6-bate.4":{"name":"alispig-advanced-chat","version":"1.5.6-bate.4","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"b03069d903a56b7a43b6afb9170a1543fe374938","_id":"alispig-advanced-chat@1.5.6-bate.4","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-kc2tcNL658nHsU2SqkQDQEiR+uLPu3/gc2lr1HUEg6e2D2b9irbxlvY0q5CJaYUYc/lijh+opy28KtukuUmLAA==","shasum":"7bbe0f9063be763d45f843e70a88a0da9b114b35","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.4.tgz","fileCount":17,"unpackedSize":22093816,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCkSuzlqpLprcEY0Z/PgG81cRTfy2Goo/rDh9WbJ4TTNgIhAJLtxv5XYgeMcaIdJDuiqyIQUQbfSmmSFy8Q49y18h6u"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi95ntACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq2CRAAmORpsEbYGpZefo/vlSIGSJdxfOoP5d8GngzvWg5Bv9DxTX+u\r\nKtWMYnluS5snz6SDGXs7PUdvQSuXEYdGdPqQdiE0e5pq1waOu+0vyVQcPe/b\r\nn/kulq8emeVotGHP1ARHHFTEBcufPFXAMZHlacI9tn0BxjjHFTbUNBHFPABo\r\nIh6fUxyFzh3iCE4LJSA8rPB9yPT11KDsp/QI7UTqBT4+306B/FWylQjYnEpY\r\njouaIrFJZhrZXmTv8jsdttPW9h7+Tk0bXlO8By+GAuYZO+CLwubaL1zwR9Te\r\nOJKGFbWSjV4/+D4JALD4Hx0DBYkL9kOVUkjaYM46plYvyql3LjHgTN3MeGz1\r\nzIuJ2A4QGN/3Fu5a/yLffkzrgpv8hCVWo1QcPkVYqPtfIy58NyhrdBnx2V9O\r\nYlbI/u/Zmf1gYw7S7OSs0ZezDU4k5T2J06HyYDZTHq/fqf8hnVkBuQ7FJL3m\r\nwhc8TCYTWxGtg7gQTas9WqKyf5GDokKHph7ypv5gnweHvwrdv0w0FMscImNF\r\nzFKkkUwWH7mtnV+sJ6DT33pdK8WcYvhBCz1ntFDHKYS4htwPUYz//GVGigVD\r\nnOr4QpLwZNLFWaX1xUTJ5JmVSoHfhdG2dnSaIBnsSR4fUkE/YliUS9lOP8Xf\r\nFiJAajRcjgRcCSlRfCXPwNJd9f9ubp/uI4o=\r\n=BUYm\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.4_1660393965523_0.5558804157033375"},"_hasShrinkwrap":false},"1.5.6-bate.5":{"name":"alispig-advanced-chat","version":"1.5.6-bate.5","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"b03069d903a56b7a43b6afb9170a1543fe374938","_id":"alispig-advanced-chat@1.5.6-bate.5","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-SoQMRtsAUv2jb060vFWKuFJUS+dqUAxwHy3ZNwlKj0a/BlcEiIhzBz3zbFwhcsETb3hOCHswbyjN++3RyzLTmg==","shasum":"037738083f974008429e2d3cb1fa05a365cbb046","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.5.tgz","fileCount":17,"unpackedSize":22098310,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCsDEw21Ki31ta+/oADRPPxSHFHG1Am4e4Uu5aFohL4ywIhAJ5VJUduvA5eKIGBZiV8buibPPvnNLwnTmOJJXmEfD3i"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi96lcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoJGxAAkhqSC5zhH5iLIc9Tm/stqXtsxi5dkM1WI6v1fXHXWTu99ib1\r\nzhi93Xw9VVNCxygzjrE5J8YgmT5/XZdHy8QinyTOtwBbQCdHReIX0XJn9QSO\r\n3Ay8YjyjGCO0/AsKXdipUUHyjS2XArcUdnj80LgYHPrj8Stg2toM9xMTmGOB\r\n39kcZaTjtCRd955CZgcD5HgdePXiCwp/Wu3U4jSdu2s4K4a4Mh/KJU1xMVxB\r\n6spTZwBDJZRZj8IsQIee9+ni2IfMOaDWSVdCQkJROG+ilfNezw0o8hZQhhNp\r\n5XzwIqxQahAmNqD+Lg9/9P9E3cUN06sBTkzjgX55QK3lMzUVbYLQpjcAdET7\r\nD86loKUfO0V5Gk0+C08nx7018zbZ3d3XXqthUAMy1vNSnmBrVsR4Lye/qBVk\r\nxjb6Z35HGrtz+776n4xBT7u+LdxmNvShjkQDBO3P3oy+SH3a3UkOZC4PZEfL\r\n9/Dhumip8fdHkDqkwvjTOC4Xy+ZCQKBelkv70Vbq3XmvmLMpQjsuG18JG92V\r\nynUuhMguW4m+0PTq8XihI5ulPjQcajTmf61un1zV0pP1DQXWz2z5Uvo/3PNp\r\nHmZXWclAjRx0wwhEZ06hn4oYlA4rx1beh7G0gF2CeifiwE+hsMyQdboJzbV7\r\nMFA0iMFucYGa9HWEdts7k9YWJXWaCKycdZs=\r\n=lBGW\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.5_1660397915866_0.4327593038340045"},"_hasShrinkwrap":false},"1.5.6-bate.6":{"name":"alispig-advanced-chat","version":"1.5.6-bate.6","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"ddc8f9079a706ea84200525080273e7d3eace314","_id":"alispig-advanced-chat@1.5.6-bate.6","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-pbZAp8/A13wLWJiiCmFF/xwhscXYg58EIVIGVxaUxOpVNMBvrVcnYJ9XC5nIxclC0iB44yC1YHmhVG0eNLrn1w==","shasum":"003d473cb7d19db80310b4b125d0f7f506b535a6","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.6.tgz","fileCount":17,"unpackedSize":22099656,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIExk6R2t6BErBg9IWJau1K3DSwhMGkKwLZ4HziTp/QGUAiEAkoMNfIhlan7ybZFH9eYCKnLe6Z11neTxVsXUub0hqws="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi96uZACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmof5xAAmRK7r7/rjGqAjkRZzovBfOW9udeAQTXvrB7xf+i0VD7oTAvk\r\n+bzxA5ZB9x/uUI+O+B1uG4cRkXUI1nwYFcLK8Q4TTVVRZ+PM6hnkgH0KOMEG\r\ngJQcpHAodjSb+5ZoZiCmvM0WR0OZkkvc/hR/OHlYade1PUiZMJdhKDdixooI\r\nT5K1wsSaL5WkbH9/3QjfY9kULG6BH+0uEFbRGc64HFPWrnw2ToegLcaXuuZ1\r\nt9iuNwf3NJAGhDdl+3RrI5xEmQQK/8PxsM3W0C9vHaUdGp/dv1CC2qt4INmy\r\nQ4NHQhZjuLQ2Gg8sZAuwr2U2dzlSVENp0Hl+NRSp0LnUTXCGCu6UwO+19tdU\r\nnjkcYoRTrMgpEDGWcqwNelKvhOvo0Kj+5TJHo1W3GewCXsb/RfwWYzFpBJQ9\r\ntHAWhNYx/D67GmMzjRb9B0xgB02SMHNBnKaGmhb0bPguUjrcXvi5Tjf6Dh0H\r\nUu/RhO+4R0ZqCeZNQCkkhHzJkoPlsP31OwFAS6n7rVxrpWa8Nf47g8ejWWNd\r\n5fUXjNQTtF0EdA6JpM46lx2c/gDwUGK1Z+pp8Opsqu4hzgnmL5rKjzIvo4Aa\r\nb4nC9C8vtiys/oriN2BJm8bqhTdhHkXdTUr8poz3Z4rGYM6ogLkkFhZtUST+\r\nAdIxjaflsJ0KjR0C3yGVYrnGI4nVpjiL5wU=\r\n=dfKg\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.6_1660398489066_0.735966848483447"},"_hasShrinkwrap":false},"1.5.6-bate.7":{"name":"alispig-advanced-chat","version":"1.5.6-bate.7","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"ddc8f9079a706ea84200525080273e7d3eace314","_id":"alispig-advanced-chat@1.5.6-bate.7","_nodeVersion":"14.14.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-zQ2SEHVwlZwi1NP6TT/lzokcu5lY5tOrQ3hQ13PxeVS8Z1e9klpmLKgEgZF4v0lZ6TJte0YYH0TUIQ7Dsd2THQ==","shasum":"9ca20e57848d1be73582085fdaa530fd318fa4dc","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.7.tgz","fileCount":17,"unpackedSize":22099354,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCW4EW9MXjNDlej9UeqqRTmLBWVaMGEOi+Nqql/RAsQEgIgJvOyfU0VSVPLdsGth0F+HvlYaMwx0SWGlojIbeMaMEA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi+Fx9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoqBQ//S7J+nDMWA79v5rTcflE7ZjGFS2j7CQ6vgGqmNgJQr28Ge4jN\r\nYAyBgtIH5u3mgOxiPr1ZBQsizwj03W7p1LbyqNxWGnnVIaIzRsIJhXEzwGRE\r\nGX7z9TNqdsdSY0acQbxKbIaWNWcJoYSh0DDlBi6+zzR2a7hp4q9ZVg4TDyeK\r\ngbKR4xzULR5F9o4t+FAr+19h468SM0lwdQvVhldxIbgKsuzKeC0LYJ5SYGhq\r\nVOwnM9W1vMD6sEoHguqn1u0XwBb9EOv91saaGZ8wp2YEenbbkT3A5opmRmQv\r\n0G0/BYP+j2MbO6mbWyxxK7nY6rUQo/kiB9+ETw1dNJuwFhfKfbbTEEMHonei\r\nODZU4OZnrZ/CfkyQbNcm6v0XuXuQQaek4DxvADbJnO4VKlvgoKKAspuhSGM0\r\nLZ0f7u/SVBM/cVrIOFAIk3aq/mZEsTpVuVEfEe8ufdwRsZeM1Jv/DVXv/Aof\r\nCmJ9srw4rqywz6F0Wx5FdBRFeQtEhP2dKpnoKFmCMueCFNx9oZ1pd4LgO0ZR\r\nScS+5YAzTP/+7x9T8GvDnYV8RboU5iud1WFWAtcfOAD4qMrmdWgljQREUbTl\r\nc+JeiY2+KW9CTXY2In1+AoGS+m+9mhP8PR99ZIxH05feh5o/ZHrjJuIwEyH+\r\nWP4+b5EEmX1E6TMt8WyZFMWmt6SRjYB8Xmw=\r\n=jiAD\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.7_1660443773626_0.1268316777921381"},"_hasShrinkwrap":false},"1.5.6-bate.8":{"name":"alispig-advanced-chat","version":"1.5.6-bate.8","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"cba400a9c5c05d59d9a660ce049fe135ad385312","_id":"alispig-advanced-chat@1.5.6-bate.8","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-MoU/4mqnytIohnSXsPVDEUNiHHkzGb9Dbu/Gqy2VHbdob+dzDALmIY7lFbLLSTKpjYzbuCg002rP+QvfYvrnmw==","shasum":"8ba6087180ec223c25d3a392b75507cd3f6d8274","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.8.tgz","fileCount":17,"unpackedSize":22100210,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDuqtiOjqmCEOOYjcjdIqFry7vv+SXZb+m9vj/g7AoT/AiEA2KH9MNEOZ6YpotlcUsOUB7eRcVBegUEzEZBdEvmuddk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjAY/nACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpJjhAAixJorlurJmI/n9/NNA/uj1XT7a1ePrFXKAh6QqFxvY/r/5GD\r\nTHPguJpHiSSJ5NRu4CrpQiNRSahnlW3GuUnvr2cP3K7zFB/xQiu2XqBdartH\r\n82bQ8+vwNLDDpckJB6zpjpJqU9qvd8BD0p7TLt01Yp6EKP8gTxhy2/DXBH9w\r\nNjb3eZXCs3rflkC1qGY2U+5/dxVPox8ruyy0QpI/ATpTsPdoMPlzt7rytbYX\r\ndPh7fRwpDlGGB16DaQETw13cGhba7ZAQiYSwkZtP5JBaLswW5ZmItCjQQ7PF\r\nt2sCt8/lGgGB7Kkg2u02KqJocNp8q529MA0v5TQw8+35Nuib2/Kjd/LOgqPa\r\nGUARnAdEeGj2kkcqYBZokSu172f5N+9N9AIhSOMDlFjr4xqDRIPWF4Qgl77n\r\nDsunqtghadBBIaIgC4U9pwUT5KewxOlipc/xNdIb2X/cKgNvrkVHu+t3yB3x\r\nqhGkcTN0j/TxOrdCiN9VG3xOUhrGq0REj66Na8XGALshzC8kVsEvkiG868Ob\r\n5Vz44dOs4bx+bzA0CuAyP6K7GvdkYZT6weL65f0gZupfw5ovI6u2ulLAhP2z\r\nMmEGluUWV/pB88BfMP8wjgOUmAKYEOzbCZrJNQYekJrtY+1KUSJrFs3D0f58\r\nXuFEC3udLTIwkmijlwE7jq3/KcDYXUgpCGs=\r\n=H656\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.8_1661046759320_0.6687546892880003"},"_hasShrinkwrap":false},"1.5.6-bate.9":{"name":"alispig-advanced-chat","version":"1.5.6-bate.9","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","alispig-vue-virtual-scroll-list":"^2.3.4-bate.1","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"87fef735fcbfd4354eaaccd7627dbc57980b3850","_id":"alispig-advanced-chat@1.5.6-bate.9","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-BjDGqBh2Akpa/3uEUe17cB6w4t9+yURj5qDe6qWjM5rYFHK5wXU9e/NLFHC70mwAo8y7RU9hmcXy8BhAUiE4gQ==","shasum":"a6404fbae5bececadfffe2a9a0e3be54f456068b","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.9.tgz","fileCount":17,"unpackedSize":22447575,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEo5DK+yYjQ49scic/RIacy0yk7RtVKGNe8vxO5Uvp4oAiEAlPAZrkdFW4cucVR388WJi7p6q4+J93TseU/+G907OOA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjDgZOACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoL8g//XSILylevhBw4t9RAoX8VWOidRPXZ5r6OOjX+EDxpeGtuNApl\r\nJZK7ABondB2ook35hVc/4fpW9XkJlev58dahZKf4vYJqDIgKjPA0eCVL5KDz\r\n41UsgZfs4Q1VS+Wn0U/e9XIlv1AReqIlX9ekUaSf0+/rC5464CFtHHtSqn2z\r\nFH03DzUKnHynbHnOwqLUVkPEv6A2rawCUGJXtXYI3EP/uhnK3tIAe5dTPju4\r\neCJ2iHopdR8XpfuBMtAcwUSdTRid/AP6J1zEoM1eYxOQYLzqb5Q937YU8PHW\r\nnBsAdWrImz2eoF64+wgS8Yppwz8+MrfhVRZS05A/MQSmOE8TxtDzvZs8J3Yw\r\ncURd5Kh7YWyZqYKbT4IcrAWPWrPlg92Nq8jXWgen/sQHKjlVF3rftPPuSZTg\r\nywGXaDeokJPQ+5pipdYcq5EyUgPpv7RLLhw5Z2WhQR17h1lnGM0MR4wkDcer\r\n4y1S3pmhR6DmDBqe2RljRhMY90ZXImbDPX7z39hPtZzYhUm2GgufydC+coW0\r\nj2tUIwFTUUH0RnPk6Sk6firmwb5/fsbXed6iNPYPzX+3GqRlYYoRsywXYPRH\r\n5RZOR6uzQBoZQ79FNyLl8hqtdMgyX4WxhS79b77jfeW35bocwFgF2K1WuHkz\r\nPGu78F3+xHpoSg0qnePVO7exm7mZxwD4qUY=\r\n=pApH\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.9_1661863501139_0.3667918741298355"},"_hasShrinkwrap":false},"1.5.6-bate.10":{"name":"alispig-advanced-chat","version":"1.5.6-bate.10","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","alispig-vue-virtual-scroll-list":"^2.3.4-bate.1","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"adcc2f36263f47cdd63e9cf7d505c6e067b0998d","_id":"alispig-advanced-chat@1.5.6-bate.10","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-2j4gAg9f5CFCDhVF1SvwFHHWcWd1m5UFA+5rzvW8YJpklPuML8dsUOvlAvjvOcX5aYOmjfFqFIsdM6tjaR34vA==","shasum":"d49e9f7fc9ea6e30fb7dd09237a7b4c77afb2e53","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.10.tgz","fileCount":17,"unpackedSize":22495763,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDBiZAYMTrDbUhMHdSvIPQmaOQrmMRyL3WN0IR8atJKjAIgc48VJqSE+teo3+qbPwg2nP911d8MZwiuljhVR+xhkJs="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjD3FgACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpGaA//TbZ1vquXLvGOHlPaq4LWqAKPuuUugKZn5r0J+m7a86su6TcF\r\nG08X2uBUrsYkZlytreIJHF3KqAmC3T3I+vieN4nYzre8EGGkP+hjZGRv9kwf\r\nsiSUuN6UhoCSOEaGMVdkV4UPajLq93P4kH981AB2H5654AIFYgEbZnz3GwJW\r\nOX1Tf+Atbqqndle8nF6wtra9ib7SjBqCrwhkLNnP765fvFUohpLBm6HF0szt\r\nkxesuSgu4IvMBe5PuZFqAbkij0ww373KAPFob4F1Dq0EfgEQho7+RywlDe9G\r\nQgLI3S7CjtZ0f6uRufYcOS/3wqG/MnCIM12uiRKeH2YyLhRsOTPeXI/ZQe/7\r\nFkx2w7zGjRahLm0mA768kgb7XmUsRXija4ylVLpQ5kSWJ0MuGZ5V2j1Sr5vm\r\nM+4GmCvc8eBAoyWon/OvBjbYTzv8hIHrDYBbrsSfC+R+UICR0fPoUwPHXlq8\r\nOJFIeYkTksudXc92B9ednUo7hntQSSTKhsWHW+XG5Opn66G3qEq6v6fv3zrG\r\nObre3h2IgUhgNPTd8GIQRXyNIO7IHFkjYWUNbQZaH+/Vqyu5eyANYBfkrsLM\r\nWHaqm4m8YjU0RZ+aIuClE32tYRi8eHYnn76PtYFwjwi1pPjIQfG/95EMu+d0\r\n+2lJTYJgRLrwG3SzRUGWauTv9wbzDh3mWVg=\r\n=xTjZ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.10_1661956448462_0.915742975638866"},"_hasShrinkwrap":false},"1.5.6-bate.11":{"name":"alispig-advanced-chat","version":"1.5.6-bate.11","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","alispig-vue-virtual-scroll-list":"^2.3.4-bate.1","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"adcc2f36263f47cdd63e9cf7d505c6e067b0998d","_id":"alispig-advanced-chat@1.5.6-bate.11","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-5DNWER+Omc8XX4e2aWGz3Q975W2INFaNzE9QT218eSXDZNDKq9XX9Q4ogSj7jSDLp2r4cyHMTTqenj7AgFOH7g==","shasum":"6cfc697277c19cdc8814d5fd6174d2f38f494087","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.11.tgz","fileCount":17,"unpackedSize":22496274,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDkxRQbQDfxG24zagBWKxMTxQM6ulE+lNA51uKgqH4wWwIgS69c58dpyexsIual/Fd4pUfsqWKD/W0/y9mun+7dlmk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjEMffACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoFqQ//dMp2Q9LaROMuAzxVRFgNKcbLbGw9Z/h2dDKW4SuXHMLZ7FYD\r\ngxOYf8RT12w/f1oxrZoKXSjKgjpkFuswIObjsuQaEn7fYg0M0lPkt683/jsq\r\nBQ2isPj6M20Qyo70Zn5GngUuraEQZfxz6/TDKMZc97ZuKrBv+ahSj4bi0XG8\r\nVhGTrJs8p5GnKaqfJNQ59sLgteTm4D8hj/LW/koqLUMhrTIj7ZBtI4S7tQ6B\r\nhAMXc9QL9KV2bO5bdulKXQQwp8DTGb9ZBfHmK7ABiD2jlPLhSqlLXQ4tY/J1\r\nQ4Mj/f6M1UsB6OLGCY9GgnloMYh1BMGn/CjcNOuJMPkxdIQvDwiqWEGMO55/\r\nHffMLho18zo+KaUcqYMd13ht8/Hs/e5dEjO3jcmgoLraEIlel8r5LDIyke5y\r\n7NDlaLX8oZKLczmlMF7o9WVX4GdDkSZ6hnarSIWYOWv37HfH1xt2A/Z72dWm\r\nDH+WfQKjILftwZXjfze7/1a2EOdMXAobQi8lnLOPLzPG0zR6FIDpHB9LCOzn\r\ntZhf9ZqbdDLjYH7QKCLaS+9t3JM2gEUuHovaAngd0CuBi7c9xLmuFbqo+ND6\r\n3vsiEPYCz/HWIwyHdLFg4yboJaK8HVOVffHss0KthieC2jiV4Vgl1xT7yQnH\r\nEjs6+AumixMErOa76SloHcHrFE+pBTX3fmk=\r\n=H58F\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.11_1662044126649_0.5437447994140299"},"_hasShrinkwrap":false},"1.5.6-bate.12":{"name":"alispig-advanced-chat","version":"1.5.6-bate.12","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","alispig-vue-virtual-scroll-list":"^2.3.4-bate.1","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"adcc2f36263f47cdd63e9cf7d505c6e067b0998d","_id":"alispig-advanced-chat@1.5.6-bate.12","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-Eh7tNZg89KdksXIePiFlbCBOJI4nWI1CIvfSjKX44Rn4vs9MWMA96OPVUMUzuzLbQ4so6mol8GZenjz3aXgQ2A==","shasum":"eec42c6a7c3e40b0bf99cb6aad38a10f5823c844","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.12.tgz","fileCount":17,"unpackedSize":22496204,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCOoAZxF2oiI/7sQcpdwBzuw7LNdWvsTlFxveSbg/7N2AIgDz3DTBkYCHvTPMIFtDZC/r7QqOL1DdVBa6bFqMiScMQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjEMtwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo3dA//a2G+pGqKCEkmoXw6sjmG7U0txYQ6E6JorT8GTBc1csxW1I59\r\nDUX9/q8gC/s4ZCF8I5Ke7y4mB26XfXnK5n7KeICSAb5ubcLcOa8mnXZ94RIP\r\nTcGKPCLPmk4hxWeRdcuuRMiH9ZK2/NNJE7B6X9v9BmfZoNSyxrIIyDhb/7LL\r\nAHWjmm3CBmoYOpA5CLNJkNFnv9TAoKa6UvPoHguDin28kpOSSmDd5bxPTuFe\r\nF4zcevWZL2JfmbkREKvQZ9IZcuqYVW8+FN0bbGpWRmoPRwhsUN7ZXL7N7HbN\r\nGICwn8gE/LIP5Ykz2dhXl2zlMvQ4wvNi9da0+HJLvqikKYtjqgixjAqjn8kB\r\nGRGvmiC4T88jAIjvY4hs++oJUyPwnQcY3o8eUFQqRkR8bkOhTHiV/DJiT/j1\r\n4CaLsFxNYFWdtsHcUM85LQLGOBncs8Mlx3orrQ6ll769sI9ue9VAPFUQiovN\r\nffxecVCYwkKeexW168k47nfFpaG2uP1IaYgVbvHMbXr6Az7lYWPCTsiGqDjr\r\nvr4Ey+fN44m/PfzysjLcL+JYVEkBZiCG/qnGIVruoDoJhHt3Ec5WScOQVnwb\r\n/z3//wDtSF9EgcASwuRRA5z32Sd5dNMsIhtXfAjlWLH0ce58Jyuph6yr+Vv8\r\nd0hnLgEscfjOhm84lIk1DsUSVew9INXOsZM=\r\n=N9AO\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.12_1662045039851_0.8281405226553717"},"_hasShrinkwrap":false},"1.5.6-bate.13":{"name":"alispig-advanced-chat","version":"1.5.6-bate.13","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","alispig-vue-virtual-scroll-list":"^2.3.4-bate.1","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"adcc2f36263f47cdd63e9cf7d505c6e067b0998d","_id":"alispig-advanced-chat@1.5.6-bate.13","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-E8HhFOdSsTZMSoOUTAiPbhkUAIv2aHPgFNxa6FfhZTcQe3Z2DgRKV0MYrl3BALlHYx3fhh2TNbrD5j2nE7YCrQ==","shasum":"e494f4e61a90b933330e7b9278002da0ee48b33e","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.13.tgz","fileCount":17,"unpackedSize":22496795,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCohYY607aX1tlKR+cDQz2hrKcn7qFDJq9cCkp26wdXqgIgZAHlsrwi0rsZXGF0OoyaXv6cTg8AEh4YP7dl6EqIl2s="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjEsROACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo/vA//eXoxhSOJuTxpzbhPRLFUes4RKdT2KkA1X5C5hSv4G74xXEb0\r\n+EcjOwVpDs4puq0z/AJSvIsY2gq9cIdDkovIkx/dhAui4EHPgmoNu4xBRrjm\r\nNdKsuiIgQ0AtnDj3jRTHOe7UnO7OIIaX2n40Ut1xdoSC3a2OUOSHNhTHjJpt\r\nAmK331BMAhlQLzTcr3mPT4X1w9FQdpimrPJjdh2lAq2nRU3sjYXGeH5q/oUP\r\nFndew7EtQ8uYKSlKTzHk39etv2i29LOtI1QotfhYchkXaGcCWJLd4Y3HgHTb\r\nqFEl3KLd92mRa5drj9vxmDMQ8bgBbj9lKMku0ukLX/8raLCQBM9mf4kcCG3h\r\nwAFvArKJtjWgtQqzEFcePFRC2CT35lrhivsJg+IKdhIhei092xrljBW6rMXE\r\ny/n3OMsslLJf5n6EOQaJiCirGpVWAOJdp5f8pKDAzuct6XdViEkcI9MZKb7v\r\nHXwpTGPYHjbFM7GnACRf32HYQowPmvJdhOItwNsLeRU2oXqST+7Ebfb7m64N\r\n7w8CcvvazhA3zEdODYYQU8IJ4DO6+LtMJrI0CsGv2MLoIJ2c28zn7As4TXDS\r\nDoJVD5MM11tW4HB6dd4c5FE0sCBlz2tzYSyHFfaGT/q/mlwJLd4PFNFSULT0\r\nUulH+d7DfB7XIvEHfAKIK1yzhH7rSdiLvMs=\r\n=HAvg\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.13_1662174285643_0.39710522597039866"},"_hasShrinkwrap":false},"1.5.6-bate.14":{"name":"alispig-advanced-chat","version":"1.5.6-bate.14","license":"MIT","description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"types":"./types/vue-advanced-chat.common.d.ts","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","main":"./dist/vue-advanced-chat.common.js","unpkg":"./dist/vue-advanced-chat.min.js","scripts":{"serve":"vue-cli-service serve","build":"npm run clean:lib && npm run build:lib && npm run build:wc","clean:lib":"rimraf dist","build:lib":"vue-cli-service build --target lib --no-clean --name vue-advanced-chat ./src/lib/index.js","build:wc":"vue-cli-service build --target wc --no-clean --name vue-advanced-chat ./src/lib/ChatWindow.vue","prepublish":"npm run lint && npm run test && npm run build","publish-beta":"npm publish --tag beta","lint":"vue-cli-service lint","test":"jest","reset":"rm -rf node_modules && rm -rf package-lock.json && npm i","reset-all":"cd demo && npm run reset-all"},"typings":"types/index.d.ts","devDependencies":{"@typescript-eslint/eslint-plugin":"^4.29.1","@typescript-eslint/parser":"^4.29.1","@vue/cli-plugin-babel":"^4.5.13","@vue/cli-plugin-eslint":"^4.5.13","@vue/cli-plugin-typescript":"^4.5.13","@vue/cli-service":"^4.5.13","@vue/eslint-config-standard":"^4.0.0","@vue/eslint-config-typescript":"^7.0.0","@vue/test-utils":"^1.1.3","babel-core":"^7.0.0-bridge.0","babel-eslint":"^10.0.3","babel-jest":"^23.6.0","eslint":"^6.8.0","eslint-plugin-vue":"^7.14.0","jest":"^23.6.0","node-sass":"^6.0.1","rimraf":"^3.0.2","sass-loader":"^10.1.1","typescript":"4.6.x","vue":"^2.6.14","vue-jest":"^3.0.7","vue-template-compiler":"^2.6.14"},"peerDependencies":{"vue":"^2.6.14"},"dependencies":{"alispig-emoji-mart-vue-fast":"10.2.2","linkifyjs":"^2.1.9","v-click-outside":"^3.1.2","alispig-vue-virtual-scroll-list":"^2.3.4-bate.1","lamejs":"1.2.0"},"optionalDependencies":{"lamejs":"1.2.0"},"readme":"<p align=\"center\">\r\n<a href=\"https://github.com/antoine92190/vue-advanced-chat/actions/workflows/build.yml\"><img src=\"https://img.shields.io/github/workflow/status/antoine92190/vue-advanced-chat/CI\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/dm/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/bundlephobia/minzip/vue-advanced-chat\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/v/vue-advanced-chat.svg\"></a>\r\n<a href=\"https://www.npmjs.com/package/vue-advanced-chat\"><img src=\"https://img.shields.io/npm/l/vue-advanced-chat.svg\"></a>\r\n</p>\r\n\r\n# vue-advanced-chat\r\n\r\n![Demo Image](demo/src/assets/web_mobile.png)\r\n\r\n## [Vue 3 compatibility 🚀](#use-in-a-vue-3-project)\r\n\r\n## Features\r\n\r\n- Vue, Angular & React compatibility\r\n- Customizeable realtime chat messaging\r\n- Backend agnostic\r\n- Images, videos, files, voice messages & emojis\r\n- Edit messages & reply to other messages\r\n- Tag users & emojis shortcut suggestions\r\n- UI elements for seen, new, deleted, typing and system messages\r\n- Text formatting - bold, italic, strikethrough, underline, code, multiline\r\n- Online / Offline users status\r\n- Flexible options and slots\r\n- Light and dark theme modes\r\n- Firestore example\r\n- Typescript, PWA, Web Component support\r\n\r\n## [Demo](https://antoine92190.github.io/vue-advanced-chat)\r\n\r\nEnjoy :smile:\r\n\r\n## [Real World Example](https://vue-advanced-chat.herokuapp.com/)\r\n\r\nA Progressive Web Application showcasing all the features of `vue-advanced-chat` component.<br>\r\nBuilt with Firestore, Vuetify, and Push Notifications.\r\n\r\nIf you wish to get premium access to the real world example source code, please contact me by email.\r\n\r\nYou will get a fully working chat application for web and mobile:\r\n\r\n- UI and backend integration\r\n- Email, Facebook and Google authentication\r\n- Real-time messaging, browser push notifications, images optimization (Firebase Cloud Functions to compress avatars)\r\n- UI/UX components for alerts (errors, information), dialogs, etc.\r\n- Add existing users to a room using their email\r\n- Send email invitations to non-existing users\r\n- Edition of profile and rooms\r\n- Addition and deletion of room users\r\n- Optimised firestore implementation to reduce bandwidth and costs as much as possible\r\n- State management using vuex\r\n- Internationalisation (i18n)\r\n- Google Analytics\r\n- Support to help you get the chat up and running\r\n\r\n## Table of Contents\r\n\r\n- [Installation](#installation)\r\n- [Usage](#example)\r\n- [Props API](#props-api)\r\n- [Props data structure](#props-data-structure)\r\n- [Events API](#events-api)\r\n- [Named Slots](#named-slots)\r\n- [Using with Firestore](#using-with-firestore)\r\n- [Use as a Web Component with React and Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n<br>\r\n\r\n## Installation\r\n\r\nThis component is only compatible with Vue `2.6.14` and above.\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue-advanced-chat\r\n\r\n# Using yarn\r\nyarn add vue-advanced-chat\r\n\r\n# Using CDN\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue@2.6.14\"></script>\r\n<script src=\"https://cdn.jsdelivr.net/npm/vue-advanced-chat@0.8.8/dist/vue-advanced-chat.min.js\"></script>\r\n```\r\n\r\nIf you want to send mp3 audio messages, you may need to install `lamejs` inside your project:\r\n\r\n```bash\r\nnpm install lamejs --save\r\n```\r\n\r\n[Installation with React & Angular](#use-as-a-web-component-with-react-and-angular)\r\n\r\n## Usage\r\n\r\n#### You can import it as a custom component:\r\n\r\n```javascript\r\n<template>\r\n  <chat-window\r\n    :current-user-id=\"currentUserId\"\r\n    :rooms=\"rooms\"\r\n    :messages=\"messages\"\r\n  />\r\n</template>\r\n\r\n<script>\r\n  import ChatWindow from 'vue-advanced-chat'\r\n  import 'vue-advanced-chat/dist/vue-advanced-chat.css'\r\n\r\n  export default {\r\n    components: {\r\n      ChatWindow\r\n    },\r\n    data() {\r\n      return {\r\n        rooms: [],\r\n        messages: [],\r\n        currentUserId: 1234\r\n      }\r\n    }\r\n  }\r\n</script>\r\n```\r\n\r\n#### Or if you used CDN import:\r\n\r\n```javascript\r\n<template>\r\n  <vue-advanced-chat/>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n  data() {\r\n    return {\r\n      rooms: [],\r\n      messages: [],\r\n      currentUserId: 1234\r\n    }\r\n  },\r\n  mounted() {\r\n    document.querySelector('vue-advanced-chat').currentUserId = this.currentUserId\r\n    document.querySelector('vue-advanced-chat').rooms = this.rooms\r\n    document.querySelector('vue-advanced-chat').messages = this.messages\r\n  }\r\n}\r\n</script>\r\n```\r\n\r\n### Important notes\r\n\r\n`vue-advanced-chat` component is performance oriented, hence you have to follow specific rules to make it work properly.\r\n\r\n- Use array assignement instead of `push` method\r\n\r\n```javascript\r\n// DO THIS\r\nconst rooms = []\r\nfor (let i = 0; i < res.length; i++) {\r\n  rooms.push(res)\r\n}\r\nthis.rooms = rooms\r\n\r\n// DON'T DO THIS\r\nfor (let i = 0; i < res.length; i++) {\r\n  this.rooms.push(res)\r\n}\r\n```\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[i].typingUsers.push(typingUserId)\r\n```\r\n\r\n- To add or replace an item inside an array, use spread operator\r\n\r\n```javascript\r\n// DO THIS\r\nthis.rooms[roomIndex] = room\r\nthis.rooms = [...this.rooms]\r\n\r\n// DON'T DO THIS\r\nthis.rooms[roomIndex] = room\r\n\r\n// AND DON'T DO THIS\r\nthis.rooms.push(room)\r\n```\r\n\r\n- Follow the UI loading pattern by updating `messagesLoaded` prop every time a new room is fetched\r\n\r\n```javascript\r\nfetchMessages({ room, options }) {\r\n  this.messagesLoaded = false\r\n\r\n  // use timeout to imitate async server fetched data\r\n  setTimeout(() => {\r\n    this.messages = []\r\n    this.messagesLoaded = true\r\n  })\r\n}\r\n```\r\n\r\n<br>\r\n\r\n## Props API\r\n\r\n| <div style=\"width:230px\">Prop</div> | Type             | Required | Default                                                                                                           |\r\n| ----------------------------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |\r\n| `height`                            | String           | -        | `600px`                                                                                                           |\r\n| `current-user-id`(1)                | [String, Number] | `true`   | -                                                                                                                 |\r\n| `rooms`                             | Array            | -        | `[]`                                                                                                              |\r\n| `rooms-order`                       | String           | -        | `desc`                                                                                                            |\r\n| `loading-rooms`(2)                  | Boolean          | -        | `false`                                                                                                           |\r\n| `rooms-loaded`(3)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `room-id`(4)                        | [String, Number] | -        | `null`                                                                                                            |\r\n| `load-first-room`(5)                | Boolean          | -        | `true`                                                                                                            |\r\n| `rooms-list-opened`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `messages`                          | Array            | -        | `[]`                                                                                                              |\r\n| `room-message`(6)                   | String           | -        | `null`                                                                                                            |\r\n| `username-options` (7)              | Object           | -        | `{minUsers: 3, currentUser: false}`                                                                               |\r\n| `messages-loaded`(8)                | Boolean          | -        | `false`                                                                                                           |\r\n| `room-actions`(9)                   | Array            | -        | `[]`                                                                                                              |\r\n| `menu-actions`(10)                  | Array            | -        | `[]`                                                                                                              |\r\n| `message-actions`(11)               | Array            | -        | (11)                                                                                                              |\r\n| `message-selection-actions`(12)     | Array            | -        | (12)                                                                                                              |\r\n| `templates-text`(13)                | Array            | -        | `null`                                                                                                            |\r\n| `auto-scroll`(14)                   | Object           | -        | `{ send: { new: true, newAfterScrollUp: true }, receive: { new: true, newAfterScrollUp: false } }`                |\r\n| `show-search`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-add-room`                     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-send-icon`                    | Boolean          | -        | `true`                                                                                                            |\r\n| `show-files`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `show-audio`                        | Boolean          | -        | `true`                                                                                                            |\r\n| `audio-bit-rate`                    | Number           | -        | `128`                                                                                                             |\r\n| `audio-sample-rate`                 | Number           | -        | `44100`                                                                                                           |\r\n| `show-emojis`                       | Boolean          | -        | `true`                                                                                                            |\r\n| `show-reaction-emojis`              | Boolean          | -        | `true`                                                                                                            |\r\n| `show-new-messages-divider`(15)     | Boolean          | -        | `true`                                                                                                            |\r\n| `show-footer`(16)                   | Boolean          | -        | `true`                                                                                                            |\r\n| `text-messages`(17)                 | Object           | -        | `null`                                                                                                            |\r\n| `text-formatting`(18)               | Object           | -        | ` {disabled: false, italic: '_', bold: '*', strike: '~', underline: '°', multilineCode: '```', inlineCode: ' `'}` |\r\n| `link-options`(19)                  | Object           | -        | `{ disabled: false, target: '_blank', rel: null }`                                                                |\r\n| `room-info-enabled` (20)            | Boolean          | -        | `false`                                                                                                           |\r\n| `textarea-action-enabled`(21)       | Boolean          | -        | `false`                                                                                                           |\r\n| `user-tags-enabled`                 | Boolean          | -        | `true`                                                                                                            |\r\n| `emojis-suggestion-enabled`         | Boolean          | -        | `true`                                                                                                            |\r\n| `media-preview-enabled`             | Boolean          | -        | `true`                                                                                                            |\r\n| `responsive-breakpoint`(22)         | Number           | -        | `900`                                                                                                             |\r\n| `single-room`(23)                   | Boolean          | -        | `false`                                                                                                           |\r\n| `scroll-distance`(24)               | Number           | -        | `60`                                                                                                              |\r\n| `theme`(25)                         | Sring            | -        | `light`                                                                                                           |\r\n| `accepted-files`(26)                | String           | -        | `*`                                                                                                               |\r\n| `styles`(27)                        | Object           | -        | (25)                                                                                                              |\r\n\r\n**(1)** `current-user-id` is required to display UI and trigger actions according to the user using the chat (ex: messages position on the right, etc.)\r\n\r\n**(2)** `loading-rooms` can be used to show/hide a spinner icon while rooms are loading\r\n\r\n**(3)** `rooms-loaded` must be set to `true` when all rooms have been loaded. Meaning the user cannot scroll to load more paginated rooms\r\n\r\n**(4)** `room-id` can be used to load a specific room at any time\r\n\r\n**(5)** `load-first-room` can be used to remove the default behaviour of opening the first room at initialization\r\n\r\n**(6)** `room-message` can be used to add a default textarea value\r\n\r\n**(7)** `username-options` can be used to show/hide room messages username according to the minimum number of users `minUsers` inside a room, and if the message user is the current user `currentUser`\r\n\r\n**(8)** `messages-loaded` must be set to `true` when all messages of a conversation have been loaded. Meaning the user cannot scroll on top to load more paginated messages\r\n\r\n**(9)** `room-actions` can be used to display your own buttons when clicking the dropdown icon of each room inside the rooms list.<br>\r\nYou can then use the [room-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nroom-actions=\"[\r\n  {\r\n    name: 'archiveRoom',\r\n    title: 'Archive Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(10)** `menu-actions` can be used to display your own buttons when clicking the vertical dots icon inside a room.<br>\r\nYou can then use the [menu-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmenu-actions=\"[\r\n  {\r\n    name: 'inviteUser',\r\n    title: 'Invite User'\r\n  },\r\n  {\r\n    name: 'removeUser',\r\n    title: 'Remove User'\r\n  },\r\n  {\r\n    name: 'deleteRoom',\r\n    title: 'Delete Room'\r\n  }\r\n]\"\r\n```\r\n\r\n**(11)** `message-actions` can be used to display your own buttons when clicking the dropdown icon inside a message.<br>\r\nYou can then use the [message-action-handler](#events-api) event to call your own action after clicking a button. Ex:\r\n\r\n```javascript\r\nmessage-actions=\"[\r\n  {\r\n    name: 'addMessageToFavorite',\r\n    title: 'Add To Favorite'\r\n  },\r\n  {\r\n    name: 'shareMessage',\r\n    title: 'Share Message'\r\n  }\r\n]\"\r\n```\r\n\r\nYou can use built-in `message-actions` names to trigger specific UI modifications when clicked.<br>\r\nCurrently, `replyMessage`, `editMessage` and `deleteMessage` action names are available.<br>\r\nIf `messageActions` is not set, it will use the default values below.<br>\r\nIf you don't want to display this `messageActions` menu, you can pass it an empty array.\r\n\r\n```javascript\r\nmessageActions=\"[\r\n  {\r\n    name: 'replyMessage',\r\n    title: 'Reply'\r\n  },\r\n  {\r\n    name: 'editMessage',\r\n    title: 'Edit Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'deleteMessage',\r\n    title: 'Delete Message',\r\n    onlyMe: true\r\n  },\r\n  {\r\n    name: 'selectMessages',\r\n    title: 'Select'\r\n  }\r\n]\"\r\n```\r\n\r\n**(12)** `message-selection-actions` is related to the above `selectMessages` message action. You can use it to display custom action buttons in the room header when selecting a message. Ex:\r\n\r\n```\r\nmessageActions=\"[\r\n  {\r\n    name: 'deleteMessages',\r\n    title: 'Delete'\r\n  },\r\n  {\r\n    name: 'forwardMessages',\r\n    title: 'Forward'\r\n  }\r\n]\"\r\n```\r\n\r\n**(13)** `templates-text` can be used to add autocomplete templates text when typing `/` in the room textarea. Ex:\r\n\r\n```javascript\r\ntemplatesText=\"[\r\n  {\r\n    tag: 'help',\r\n    text: 'This is the help'\r\n  },\r\n  {\r\n    tag: 'action',\r\n    text: 'This is the action'\r\n  }\r\n]\"\r\n```\r\n\r\n**(14)** `auto-scroll` can be used to change the auto scroll behaviour when sending/receiving a message. Ex:\r\n\r\n```javascript\r\nauto-scroll=\"{\r\n  send: {\r\n    new: true, // will scroll down after sending a message\r\n    newAfterScrollUp: false // will not scroll down after sending a message when scrolled up\r\n  },\r\n  receive: {\r\n    new: false, // will not scroll down when receiving a message\r\n    newAfterScrollUp: true // will scroll down when receiving a message when scrolled up\r\n  }\r\n}\"\r\n```\r\n\r\n**(15)** `show-new-messages-divider` can be used to show/hide the blue line divider between seen and unseen messages.\r\n\r\n**(16)** `show-footer` can be used to hide the room footer. For example to prevent users to send any message or media.\r\n\r\n**(17)** `text-messages` can be used to replace default i18n texts. Ex:\r\n\r\n```javascript\r\ntext-messages=\"{\r\n  ROOMS_EMPTY: 'Aucune conversation',\r\n  ROOM_EMPTY: 'Aucune conversation sélectionnée',\r\n  NEW_MESSAGES: 'Nouveaux messages',\r\n  MESSAGE_DELETED: 'Ce message a été supprimé',\r\n  MESSAGES_EMPTY: 'Aucun message',\r\n  CONVERSATION_STARTED: 'La conversation a commencée le :',\r\n  TYPE_MESSAGE: 'Tapez votre message',\r\n  SEARCH: 'Rechercher',\r\n  IS_ONLINE: 'est en ligne',\r\n  LAST_SEEN: 'dernière connexion ',\r\n  IS_TYPING: 'est en train de taper...',\r\n  CANCEL_SELECT_MESSAGE: 'Annuler Sélection'\r\n}\"\r\n```\r\n\r\n**(18)** `text-formatting` can be used to add text formatting. Bold, italic, strikethrough, underline, inline code and multiline code formatting are currently available and can be used in conjonction.\r\n\r\n- You can disable text formatting by passing the prop `:text-formatting=\"{disabled: true}\"`.\r\n- You can change markdown characters, for example: `:text-formatting=\"{italic: '^'}\"`\r\n- You can disable a specific markdown character, for example: `:text-formatting=\"{bold: null}\"`\r\n\r\n| Style             | Syntax          | Example                                | Output                                 |\r\n| ----------------- | --------------- | -------------------------------------- | -------------------------------------- |\r\n| Bold              | `* *`           | `*This is bold text*`                  | **This is bold text**                  |\r\n| Italic            | `_ _`           | `_This text is italicized_`            | _This text is italicized_              |\r\n| Strikethrough     | `~ ~`           | `~This was mistaken text~`             | ~~This was mistaken text~~             |\r\n| Underline         | `° °`           | `°This text is underlined°`            | <ins>This text is underlined</ins>     |\r\n| Nested formatting | `* *` and `_ _` | `*This text is _extremely_ important*` | **This text is _extremely_ important** |\r\n\r\n**Inline Code**\r\n\r\nExample: \\`This is inline code\\`\r\n\r\nOutput: `This is inline code`\r\n\r\n**Multiline Code**\r\n\r\nExample: \\```This is multiline code\\```\r\n\r\nOutput:\r\n\r\n```bash\r\nThis is\r\nmultiline code\r\n```\r\n\r\n**(19)** `link-options` can be used to disable url links in messages, or change urls target. Ex:\r\n\r\n```javascript\r\n:link-options=\"{ disabled: true, target: '_self', rel: null }\"\r\n```\r\n\r\n**(20)** `room-info-enabled` can be used to trigger an event after clicking the room header component.<br>\r\nYou can then use the [room-info](#events-api) event to call your own action after clicking the header.\r\n\r\n**(21)** `textarea-action-enabled` can be used to add an extra icon on the right of the textarea<br>\r\nYou can then use the [textarea-action-handler](#events-api) event to call your own action after clicking the icon.\r\n\r\n**(22)** `responsive-breakpoint` can be used to collapse the rooms list on the left when then viewport size goes below the specified width.\r\n\r\n**(23)** `single-room` can be used if you never want to show the rooms list on the left. You still need to pass the `rooms` prop as an array with a single element.\r\n\r\n**(24)** `scroll-distance` can be used to change the number of pixels before `fetchMessages` event is triggered when scrolling up to load more messages, or `fetchMoreRooms` event is triggered when scrolling down to load more rooms.\r\n\r\n**(25)** `theme` can be used to change the chat theme. Currently, only `light` and `dark` are available.\r\n\r\n**(26)** `accepted-files` can be used to set specifics file types allowed in chat. By default, all file types are allowed: `\"*\"`.\r\n\r\nExample: set `\"accepted-files=\"image/png, image/jpeg, application/pdf\"` to allow `JPG` `PNG` and `PDF` files only\r\n\r\n**(27)** `styles` can be used to customize your own theme. You can find the full list [here](src/themes/index.js)\r\n\r\n```javascript\r\nstyles=\"{\r\n  general: {\r\n    color: '#0a0a0a',\r\n    colorSpinner: '#333',\r\n    borderStyle: '1px solid #e1e4e8'\r\n  },\r\n\r\n  footer: {\r\n    background: '#f8f9fa',\r\n    backgroundReply: 'rgba(0, 0, 0, 0.08)'\r\n  },\r\n\r\n  icons: {\r\n    search: '#9ca6af'\r\n  }\r\n}\"\r\n```\r\n\r\n## Props data structure\r\n\r\nYour props must follow a specific structure to display rooms and messages correctly:\r\n\r\n### Rooms prop\r\n\r\n```javascript\r\nrooms=\"[\r\n  {\r\n    roomId: 1,\r\n    roomName: 'Room 1',\r\n    avatar: 'assets/imgs/people.png',\r\n    unreadCount: 4,\r\n    index: 3,\r\n    lastMessage: {\r\n      content: 'Last message received',\r\n      senderId: 1234,\r\n      username: 'John Doe',\r\n      timestamp: '10:20',\r\n      saved: true,\r\n      distributed: false,\r\n      seen: false,\r\n      new: true\r\n    },\r\n    users: [\r\n      {\r\n        _id: 1234,\r\n        username: 'John Doe',\r\n        avatar: 'assets/imgs/doe.png',\r\n        status: {\r\n          state: 'online',\r\n          lastChanged: 'today, 14:30'\r\n        }\r\n      },\r\n      {\r\n        _id: 4321,\r\n        username: 'John Snow',\r\n        avatar: 'assets/imgs/snow.png',\r\n        status: {\r\n          state: 'offline',\r\n          lastChanged: '14 July, 20:00'\r\n        }\r\n      }\r\n    ],\r\n    typingUsers: [ 4321 ]\r\n  }\r\n]\"\r\n```\r\n\r\n- If you add the `index` property, your rooms will be ordered using this value.\r\n  `index` can be any sortable value, like a `string`, `datetime`, `timestamp`, etc.\r\n\r\n- For each room user, you can add the `status` property, which can hold the `state` and `lastChanged` properties:\r\n\r\n  - `state` can be `'online'` or `'offline'`\r\n  - `lastChanged` is the date when `state` was last modified.\r\n\r\n- `typingUsers` is an array of all the users who are currently writing a message\r\n\r\n### Messages prop\r\n\r\nMessage objects are rendered differently depending on their type. Text, emoji, image, video and file types are supported.<br><br>\r\nEach message object has a `senderId` field which holds the id of the corresponding agent. If `senderId` matches the `currentUserId` prop, specific UI and actions will be implemented.<br><br>\r\nNotes:\r\n\r\n- `username` will be displayed on each message of corresponding agents if at least 3 users are in the room\r\n- `system` is used to show messages with a specific centered display\r\n- `indexId` can be used if you need to change a message ID that is already displayed in a room, this preventing an animation glitch. For example, when you don't know in advance the message ID your backend will create.\r\n\r\nMessage states:\r\n\r\n- `saved: true` one checkmark\r\n- `distributed: true` two checkmarks\r\n- `seen: true` two blue checkmarks\r\n- `deleted: true` grey background with deleted message text\r\n- `failure: true` red clickable failure icon\r\n\r\n```javascript\r\nmessages=\"[\r\n  {\r\n    _id: 7890,\r\n    indexId: 12092,\r\n    content: 'Message 1',\r\n    senderId: 1234,\r\n    username: 'John Doe',\r\n    avatar: 'assets/imgs/doe.png',\r\n    date: '13 November',\r\n    timestamp: '10:20',\r\n    system: false,\r\n    saved: true,\r\n    distributed: true,\r\n    seen: true,\r\n    deleted: false,\r\n    failure: true,\r\n    disableActions: false,\r\n    disableReactions: false,\r\n    files: [\r\n      {\r\n        name: 'My File',\r\n        size: 67351,\r\n        type: 'png',\r\n        audio: true,\r\n        duration: 14.4,\r\n        url: 'https://firebasestorage.googleapis.com/...',\r\n        preview: 'data:image/png;base64,iVBORw0KGgoAA...',\r\n        progress: 88\r\n      }\r\n    ],\r\n    reactions: {\r\n      😁: [\r\n        1234, // USER_ID\r\n        4321\r\n      ],\r\n      🥰: [\r\n        1234\r\n      ]\r\n    },\r\n    replyMessage: {\r\n      content: 'Reply Message',\r\n      senderId: 4321,\r\n      files: [\r\n        {\r\n          name: 'My Replied File',\r\n          size: 67351,\r\n          type: 'png',\r\n          audio: true,\r\n          duration: 14.4,\r\n          url: 'https://firebasestorage.googleapis.com/...',\r\n          preview: 'data:image/png;base64,iVBORw0KGgoAA...'\r\n        }\r\n      ]\r\n    },\r\n  }\r\n]\"\r\n```\r\n\r\n<br>\r\n\r\n## Events API\r\n\r\n| <div style=\"width:230px\">Event</div>  | Params                                                                    | Fires when a user                               |\r\n| ------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------- |\r\n| `fetch-messages`(1)                   | `{ room, options }`                                                       | Scrolled on top to load more messages           |\r\n| `fetch-more-rooms`(2)                 | -                                                                         | Scrolled to load more rooms                     |\r\n| `send-message`                        | `{ roomId, content, files(10), replyMessage(11), usersTag }`              | Sent a message                                  |\r\n| `edit-message`                        | `{ roomId, messageId, newContent, files(9), replyMessage(11) ,usersTag }` | Edited a message                                |\r\n| `delete-message`                      | `{ roomId, message }`                                                     | Deleted a message                               |\r\n| `open-file`                           | `{ message, file }`                                                       | Clicked to view or download a file              |\r\n| `open-user-tag`(3)                    | `{ user }`                                                                | Clicked on a user tag inside a message          |\r\n| `open-failed-message`                 | `{ roomId, message }`                                                     | Clicked on the failure icon next to a message   |\r\n| `add-room`                            | -                                                                         | Clicked on the plus icon next to searchbar      |\r\n| `room-action-handler`(4)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `menu-action-handler`(5)              | `{ roomId, action }`                                                      | Clicked on the vertical dots icon inside a room |\r\n| `message-action-handler`(6)           | `{ roomId, action, message }`                                             | Clicked on the dropdown icon inside a message   |\r\n| `message-selection-action-handler`(7) | `{ roomId, action, messages }`                                            | Clicked on the select button inside a message   |\r\n| `send-message-reaction`               | `{ roomId, messageId, reaction, remove }`                                 | Clicked on the emoji icon inside a message      |\r\n| `room-info` (8)                       | `room`                                                                    | Clicked the room header bar                     |\r\n| `toggle-rooms-list`                   | `{ opened }`                                                              | Clicked on the toggle icon inside a room header |\r\n| `textarea-action-handler`(9)          | `{ roomId, message }`                                                     | Clicked on custom icon inside the footer        |\r\n| `typing-message`                      | `{ roomId, message }`                                                     | Started typing a message                        |\r\n\r\n**(1)** `fetch-messages` is triggered every time a room is opened. If the room is opened for the first time, the `options` param will hold `reset: true`.<br>\r\n**(1)** `fetch-messages` should be a method implementing a pagination system. Its purpose is to load older messages of a conversation when the user scroll on top.\r\n\r\n**(2)** `fetch-more-rooms` is triggered when scrolling down the rooms list, and should be a method implementing a pagination system.\r\n\r\n**(3)** `open-user-tag` is triggered when clicking a user tag inside a message. When creating a user tag by typing `@` in the footer textarea and sending the message, the tag will be identified with the below pattern:\r\n\r\n```javascript\r\n<usertag>TAGGED_USER_ID</usertag>\r\n```\r\n\r\nThis will make the tag clickable inside a message. Ex: [message tag content](#messages-collection-inside-a-room-document)<br>\r\n`send-message` and `edit-message` events will handle that pattern for you and pass it in the `content` param.\r\n\r\n**(4)** `room-action-handler` is the result of the [`room-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `room-actions` array, `room-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'archiveRoom':\r\n      // call a method to archive the room\r\n  }\r\n}\r\n```\r\n\r\n**(5)** `menu-action-handler` is the result of the [`menu-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `menu-actions` array, `menu-action-handler` will give you the name of the button that was click.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmenuActionHandler({ roomId, action }) {\r\n  switch (action.name) {\r\n    case 'inviteUser':\r\n      // call a method to invite a user to the room\r\n    case 'removeUser':\r\n      // call a method to remove a user from the room\r\n    case 'deleteRoom':\r\n      // call a method to delete the room\r\n  }\r\n}\r\n```\r\n\r\n**(6)** `message-action-handler` is the result of the [`message-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-actions` array, `message-action-handler` will give you the name of the button that was click and the corresponding message data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'addMessageToFavorite':\r\n      // call a method to add a message to the favorite list\r\n    case 'shareMessage':\r\n      // call a method to share the message with another user\r\n  }\r\n}\r\n```\r\n\r\n**(7)** `message-selection-action-handler` is the result of the [`message-selection-actions`](#props-api) prop.<br>\r\nWhen clicking a button from your `message-selection-actions` array, `message-selection-action-handler` will give you the name of the button that was click and the corresponding selected messages data.\r\nThen you can do anything you want with it. Ex:\r\n\r\n```javascript\r\nmessageActionHandler({ roomId, action, message }) {\r\n  switch (action.name) {\r\n    case 'deleteMessages':\r\n      // call a method to delete selected messaged\r\n    case 'shareMessage':\r\n      // call a method to share selected messaged with another user\r\n  }\r\n}\r\n```\r\n\r\n**(8)** `room-info` is the result of the [`room-info-enabled`](#props-api) prop.<br>\r\n\r\n**(9)** `textarea-action-handler` is the result of the [`textarea-action-enabled`](#props-api) prop.<br>\r\n\r\n**(10)** Array of files where each file contain: `{ blob, localURL, name, size, type, extension }`\r\n\r\n**(11)** `replyMessage` object is available when the user replied to another message by clicking the corresponding icon, and contains the message information that was clicked.\r\n\r\n<br>\r\n\r\n## Named Slots\r\n\r\nExample:\r\n\r\n```javascript\r\n<template #room-header=\"{ room, userStatus }\">\r\n  {{ room.roomName }} - {{ userStatus }}\r\n</template>\r\n```\r\n\r\n| <div style=\"width:230px\">Slot</div> | Action                                                      | Data                                | Overridden slots                                                                                                   |\r\n| - | - | - | - |\r\n| `custom-action-icon`                | Add a custom icon inside the footer                         | -                                          | -                                                                                                                  |     | `rooms-header` | Add a template on top of rooms list (above the search bar) | -   | -   |\r\n| `room-list-item`                    | Replace the template of the room list items                 | `room`                                     | `room-list-avatar`, `room-list-options`                                                                            |\r\n| `room-list-avatar`                  | Replace the avatar of room list items                       | `room`                                     |                                                                                                                    |\r\n| `room-list-options`                 | Replace the template of the list room options               | `room`                                     | `room-list-options-icon`                                                                                           |\r\n| `rooms-header`                      | Replace the content above the search bar                    | -                                          | -                                                                                                                  |\r\n| `rooms-list-search`                 | Replace the search bar                                      | -                                          | -                                                                                                                  |\r\n| `room-header`                       | Replace the template of the room header                     | `room`, `typingUsers`, `userStatus`        | `room-options`, `menu-icon`, `toggle-icon`                                                                         |\r\n| `room-header-avatar`                | Replace the template of the room header avatar              | `room`                                     |\r\n| `room-header-info`                  | Replace the template of the room header text                | `room`, `typingUsers`, `userStatus`        |\r\n| `room-options`                      | Replace the template of the room options                    | -                                          | menu-icon                                                                                                          |\r\n| `message`                           | Replace the template of the message box                     | `message`                                  | `deleted-icon`, `eye-icon`, `document-icon`, `pencil-icon`, `checkmark-icon`, `dropdown-icon`, `emoji-picker-icon` |\r\n| `message-failure`                   | Replace the message failure icon                            | -                                          | -                                                                                                                  |\r\n| `messages-empty`                    | Replace the empty message template                          | -                                          | -                                                                                                                  |\r\n| `rooms-empty`                       | Replace the empty rooms template                            | -                                          | -                                                                                                                  |\r\n| `no-room-selected`                  | Replace the no room selected template                       | -                                          | -                                                                                                                  |\r\n| `menu-icon`                         | Replace the room menu icon                                  | -                                          | -                                                                                                                  |\r\n| `toggle-icon`                       | Replace the toggle room list icon                           | -                                          | -                                                                                                                  |\r\n| `spinner-icon`                      | Replace the loading spinner icon                            | `show, infinite`                           | -                                                                                                                  |\r\n| `scroll-icon`                       | Replace the scroll to newest message icon                   | -                                          | -                                                                                                                  |\r\n| `reply-close-icon`                  | Replace the reply close icon                                | -                                          | -                                                                                                                  |\r\n| `image-close-icon`                  | Replace the image close icon                                | -                                          | -                                                                                                                  |\r\n| `file-icon`                         | Replace the file icon                                       | -                                          | -                                                                                                                  |\r\n| `file-close-icon`                   | Replace the file close icon                                 | -                                          | -                                                                                                                  |\r\n| `edit-close-icon`                   | Replace the edit close icon                                 | -                                          | -                                                                                                                  |\r\n| `preview-close-icon`                | Replace the media preview close icon                        | -                                          | -                                                                                                                  |\r\n| `emoji-picker-icon`                 | Replace the emoji picker icon                               | -                                          | -                                                                                                                  |\r\n| `emoji-picker-reaction-icon`        | Replace the emoji picker reaction icon (in the message box) | -                                          | -                                                                                                                  |\r\n| `paperclip-icon`                    | Replace the paperclip icon                                  | -                                          | -                                                                                                                  |\r\n| `send-icon`                         | Replace the message send icon                               | -                                          | -                                                                                                                  |\r\n| `eye-icon`                          | Replace the eye icon (image message)                        | -                                          | -                                                                                                                  |\r\n| `document-icon`                     | Replace the document icon                                   | -                                          | -                                                                                                                  |\r\n| `pencil-icon`                       | Replace the pencil icon                                     | -                                          | -                                                                                                                  |\r\n| `checkmark-icon`                    | Replace the checkmark icon                                  | `message`                                  | -                                                                                                                  |\r\n| `deleted-icon`                      | Replace the deleted icon                                    | `deleted`                                  | -                                                                                                                  |\r\n| `microphone-icon`                   | Replace the microphone icon                                 |                                            | -                                                                                                                  |\r\n| `dropdown-icon`                     | Replace the dropdown icon                                   | -                                          | -                                                                                                                  |\r\n| `room-list-options-icon`            | Replace the room list options dropdown icon                 | -                                          | -                                                                                                                  |\r\n| `search-icon`                       | Replace the search icon                                     | -                                          | -                                                                                                                  |\r\n| `add-icon`                          | Replace the add room icon                                   | -                                          | -                                                                                                                  |\r\n| `audio-pause-icon`                  | Replace the message audio pause icon                        | -                                          | -                                                                                                                  |\r\n| `audio-play-icon`                   | Replace the message audio play icon                         | -                                          | -                                                                                                                  |\r\n| `emoji-picker`                      | Replace the emoji picker component                          | `emojiOpened`, `addEmoji({ unicode: 😁 })` | `emoji-picker-reaction-icon`                                                                                       |\r\n\r\n<br>\r\n\r\n## Using with Firestore\r\n\r\n### Source code\r\n\r\nYou can find the source code to implement a full featured chat app using Firebase/Firestore inside the `demo` folder.\r\n<br>\r\nTo test it using your own Firebase project:\r\n\r\n- Setup Cloud Firestore (to store users and rooms) and Realtime Database (to store users online status)\r\n- Clone this repository: `git clone https://github.com/antoine92190/vue-advanced-chat.git`\r\n- Inside `demo/src/firestore/index.js` file, replace the line `const config = ...` by your own Firebase config\r\n- Go inside `demo` folder and run `npm run serve`\r\n\r\n### Data structure\r\n\r\nIf you decide to use the same code as in the `demo` folder to create your chat app, you need to have a specific Firestore data structure.<br>\r\nTo help you get started, I added in `demo/src/App.vue` a method `addData` to initialize some data on your Firestore database.\r\n\r\n#### Users collection\r\n\r\n```javascript\r\nusers: {\r\n  USER_ID_1: {\r\n    _id: 1,\r\n    username: 'User 1'\r\n  },\r\n  USER_ID_2: {\r\n    _id: 2,\r\n    username: 'User 2'\r\n  },\r\n  USER_ID_3: {\r\n    _id: 3,\r\n    username: 'User 2'\r\n  }\r\n}\r\n```\r\n\r\n#### Rooms collection\r\n\r\n```javascript\r\nchatRooms: {\r\n  ROOM_ID_1: {\r\n    users: [1, 3]\r\n  },\r\n  ROOM_ID_2: {\r\n    users: [1, 2, 3]\r\n  }\r\n}\r\n```\r\n\r\n#### Messages collection inside a room document\r\n\r\n```javascript\r\nmessages: {\r\n  MESSAGE_ID_1: {\r\n    content: 'My first message to <usertag>John</usertag>',\r\n    senderId: 2,\r\n    timestamp: 'December 11, 2019 at 4:00:00 PM',\r\n    seen: true\r\n  }\r\n}\r\n```\r\n\r\n#### Notes\r\n\r\n- You need to create a composite index to order rooms by last message received.\r\n  The easiest way to do it is to create a room, then click the error message url in the browser debugging console.\r\n\r\n<br>\r\n\r\n## Use as a Web Component with React and Angular\r\n\r\n### Install vue-advance-chat component\r\n\r\n- Follow [Installation](#installation) steps\r\n\r\n### Install Vue.js\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save vue\r\n\r\n# Using yarn\r\nyarn add --save vue\r\n```\r\n\r\n### React Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/react\r\n\r\n### Angular Setup\r\n\r\nSee demo repository: https://github.com/antoine92190/vue-advanced-chat-sandbox/tree/angular\r\n\r\n```jsonc\r\n// angular.json\r\n\r\n\"build\": {\r\n  \"scripts\": [\r\n    \"./node_modules/vue/dist/vue.min.js\",\r\n    \"./node_modules/vue-advanced-chat/dist/vue-advanced-chat.min.js\"\r\n  ]\r\n}\r\n```\r\n\r\n```javascript\r\n// page.module.ts\r\n\r\n@NgModule({\r\n  ...\r\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n})\r\n```\r\n\r\n```html\r\n<!-- page.html -->\r\n\r\n<vue-advanced-chat\r\n  height=\"100vh\"\r\n  [currentUserId]=\"currentUserId\"\r\n  [roomId]=\"roomId\"\r\n  [rooms]=\"rooms\"\r\n  [roomsLoaded]=\"true\"\r\n  [messages]=\"messages\"\r\n  [messagesLoaded]=\"messagesLoaded\"\r\n  [showFiles]=\"true\"\r\n  [showEmojis]=\"true\"\r\n  [showReactionEmojis]=\"true\"\r\n  [showFooter]=\"true\"\r\n  (fetch-messages)=\"fetchMessages($event.detail[0])\"\r\n  (send-message)=\"sendMessage($event.detail[0])\"\r\n  ...\r\n>\r\n</vue-advanced-chat>\r\n```\r\n\r\n<br>\r\n\r\n## Use in a Vue 3 project\r\n\r\n### Install vue-advance-chat component (next branch)\r\n\r\n```bash\r\n# Using npm\r\nnpm install --save https://github.com/antoine92190/vue-advanced-chat/tarball/next\r\n```\r\n\r\n<br>\r\n\r\n## [Contributing](https://github.com/antoine92190/vue-advanced-chat/blob/master/.github/CONTRIBUTING.md)\r\n\r\nYour help is always appreciated :rocket:\r\n\r\n## License\r\n\r\nThis project is licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License)\r\n","readmeFilename":"README.md","gitHead":"adcc2f36263f47cdd63e9cf7d505c6e067b0998d","_id":"alispig-advanced-chat@1.5.6-bate.14","_nodeVersion":"14.18.0","_npmVersion":"6.14.15","dist":{"integrity":"sha512-DD2vAkYrtLAF3cyrNBglmnMPjjbZcJbQovpNOqZIsx/vFyeJYNpSCvV7QBB25W5eYRf1DKDCWAQEMplAvIwHOA==","shasum":"0824830fa612b08cb747cb785e38c7a6026253fe","tarball":"https://registry.npmjs.org/alispig-advanced-chat/-/alispig-advanced-chat-1.5.6-bate.14.tgz","fileCount":17,"unpackedSize":22491573,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGQXf4h/usH6sVJlKlYeH8IdgEbqxYMiTzm7nIJtiVZBAiEA0B0a/SVEzXHk3whaSNP71+YEXUcYW5o/CMUp61i1G30="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjHIoAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmofqg//XdOoP1R0fAjMSzG62v2UJcZX9ytMYJIO0j92Lslvf+2+CnVe\r\nTnpQRXdF5RXoVz4xX0MlWKowoeGUX3eS+DJqd2+g/YOIYff9dCHy+Z4NHRc4\r\nbDePpy4QFu6Thhq/d4WjdnFg/zKHPnTs5bzuAsSKGZZfZhcpz3ld69RSVFed\r\n2o3CnO0mNj0wJbzX5yK6hBlr9uI+CuxONZFeEik2pirpnIPCjYoNy4TezSS/\r\n7QTeQ4QOZXpJRsJ4nAn1vKB4FHc4Qb+ygKYfGN/V2G9bBaQY61EpobCkMDf5\r\n027CNblJ3SuL94zjgr8xPAfdV+cHCdaLOb0xClKMnt8PXLsDd92Qj066iQzV\r\n9gk3IMj9rwWvLPGRwHPRrmNjDnwIrsBZYXkXQMtdLln1hXH68D6RhAYEb+2o\r\nJnnC0x8NAeQ09I7z6RgLKJvG7pWiQI3gE9nWtDlxDbVzDGB8oE5u4R8jsMWJ\r\nyFdXlL72GZCJnOX+h7Vx0PvQZH/0XXIF/Y4XoQu7sIicTWzcLwqynplKHzZj\r\nSgHPQAN9KjDhJjwo1iUdSG+everIeqCCKbEKwf2uxWDp/4Uot+IMm35KJBrF\r\nTytp3h4EacZXwkcACgwlqoayUs1GbFiBYh51Ccx9PW8GuhtiPehlJXwd3JUQ\r\ncvvcqENM84IytIeaA6QsrYwR5VIW+ByDMsw=\r\n=FUAr\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"just0351","email":"473302042@qq.com"},"directories":{},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alispig-advanced-chat_1.5.6-bate.14_1662814719926_0.8037771927592123"},"_hasShrinkwrap":false}},"time":{"created":"2021-12-11T14:33:05.165Z","1.4.2":"2021-12-11T14:33:05.381Z","modified":"2022-09-10T12:58:40.311Z","1.4.3":"2021-12-20T11:03:14.453Z","1.4.4":"2022-01-01T06:25:37.307Z","1.4.5-bate.0":"2022-01-04T02:35:27.690Z","1.4.5-bate.1":"2022-01-04T04:22:21.402Z","1.4.5-bate.2":"2022-01-04T07:46:34.436Z","1.4.5-bate.3":"2022-01-04T11:02:50.259Z","1.4.5-bate.4":"2022-01-04T11:31:18.045Z","1.4.5-bate.5":"2022-01-04T11:44:07.922Z","1.4.5-bate.6":"2022-01-04T14:38:02.578Z","1.4.5-bate.7":"2022-01-05T06:19:28.719Z","1.5.1-bate.0":"2022-01-19T09:24:47.617Z","1.5.3":"2022-03-06T15:21:54.295Z","1.5.4-beta.0":"2022-04-17T10:23:51.005Z","1.5.4-beta.1":"2022-04-18T02:45:19.325Z","1.5.4-beta.2":"2022-04-20T02:01:03.689Z","1.5.4-beta.3":"2022-05-05T09:26:50.176Z","1.5.4-beta.4":"2022-05-07T08:10:21.658Z","1.5.4-beta.5":"2022-05-08T08:22:38.793Z","1.5.4-beta.6":"2022-05-08T08:54:24.813Z","1.5.4-beta.7":"2022-06-27T04:25:29.602Z","1.5.4-beta.8":"2022-06-27T06:43:56.695Z","1.5.4-beta.9":"2022-06-27T07:23:03.410Z","1.5.4-beta.10":"2022-06-28T02:43:18.992Z","1.5.4-beta.11":"2022-06-28T03:16:54.795Z","1.5.4-beta.12":"2022-06-28T04:31:10.482Z","1.5.4-beta.13":"2022-06-28T05:52:35.580Z","1.5.4-beta.14":"2022-06-28T06:33:46.011Z","1.5.4-beta.15":"2022-06-28T09:22:10.820Z","1.5.4-beta.16":"2022-06-28T14:54:14.834Z","1.5.4-beta.17":"2022-06-29T01:21:29.097Z","1.5.4-beta.18":"2022-06-29T02:18:23.399Z","1.5.4-beta.19":"2022-07-04T13:19:02.507Z","1.5.4-beta.20":"2022-07-04T15:16:36.957Z","1.5.4-beta.21":"2022-07-11T15:40:47.500Z","1.5.4-beta.22":"2022-07-12T16:17:03.068Z","1.5.4-beta.23":"2022-07-13T08:30:29.526Z","1.5.4-beta.24":"2022-07-13T10:25:21.606Z","1.5.4-beta.25":"2022-07-15T14:27:00.254Z","1.5.4-beta.26":"2022-07-18T06:59:25.254Z","1.5.4-beta.27":"2022-07-18T07:22:22.484Z","1.5.4-beta.28":"2022-07-18T07:34:02.177Z","1.5.4-beta.29":"2022-07-21T08:37:04.502Z","1.5.5-beta.1":"2022-07-26T03:13:17.066Z","1.5.5-beta.2":"2022-07-26T06:15:18.892Z","1.5.5-beta.3":"2022-07-27T01:48:22.658Z","1.5.5-beta.4":"2022-07-27T15:50:27.061Z","1.5.5-beta.5":"2022-07-28T01:15:00.636Z","1.5.5-beta.6":"2022-07-28T03:53:28.556Z","1.5.5-beta.7":"2022-07-28T03:58:36.059Z","1.5.5-beta.8":"2022-08-02T10:08:06.308Z","1.5.5-beta.9":"2022-08-02T10:48:19.733Z","1.5.5-beta.10":"2022-08-02T10:59:19.586Z","1.5.5-beta.11":"2022-08-03T10:40:22.634Z","1.5.6":"2022-08-05T16:14:27.675Z","1.5.6-bate.0":"2022-08-10T16:56:56.272Z","1.5.6-bate.1":"2022-08-10T17:21:22.462Z","1.5.6-bate.2":"2022-08-13T10:05:37.619Z","1.5.6-bate.3":"2022-08-13T10:13:49.452Z","1.5.6-bate.4":"2022-08-13T12:32:45.891Z","1.5.6-bate.5":"2022-08-13T13:38:36.266Z","1.5.6-bate.6":"2022-08-13T13:48:09.359Z","1.5.6-bate.7":"2022-08-14T02:22:53.955Z","1.5.6-bate.8":"2022-08-21T01:52:39.657Z","1.5.6-bate.9":"2022-08-30T12:45:02.150Z","1.5.6-bate.10":"2022-08-31T14:34:08.812Z","1.5.6-bate.11":"2022-09-01T14:55:27.057Z","1.5.6-bate.12":"2022-09-01T15:10:40.171Z","1.5.6-bate.13":"2022-09-03T03:04:45.991Z","1.5.6-bate.14":"2022-09-10T12:58:40.230Z"},"maintainers":[{"name":"just0351","email":"473302042@qq.com"}],"description":"A beautiful chat rooms component made with Vue.js - compatible with Vue, React & Angular","homepage":"https://github.com/antoine92190/vue-advanced-chat#readme","keywords":["vue","vuejs","chat","vue-js-chat","multiple","group","rooms","realtime"],"repository":{"type":"git","url":"git+https://github.com/antoine92190/vue-advanced-chat.git"},"author":{"name":"Antoine Dupont","email":"antoindupontdev@gmail.com"},"bugs":{"url":"https://github.com/antoine92190/vue-advanced-chat/issues"},"license":"MIT","readme":"","readmeFilename":""}