vue-parley 4.9.2 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +26 -4
  2. package/dist/chat.css +412 -68
  3. package/dist/chunks/Call-DvVJ7IsY.mjs +1717 -0
  4. package/dist/chunks/Call-DvVJ7IsY.mjs.map +1 -0
  5. package/dist/chunks/Call-h9r4EZ5Y.cjs +1717 -0
  6. package/dist/chunks/Call-h9r4EZ5Y.cjs.map +1 -0
  7. package/dist/chunks/data-CsUe_T0I.cjs +1894 -0
  8. package/dist/chunks/data-CsUe_T0I.cjs.map +1 -0
  9. package/dist/chunks/data-VApcOLKg.mjs +1894 -0
  10. package/dist/chunks/data-VApcOLKg.mjs.map +1 -0
  11. package/dist/chunks/duotone-CZ2lLMty.cjs +95 -0
  12. package/dist/chunks/duotone-CZ2lLMty.cjs.map +1 -0
  13. package/dist/chunks/duotone-DWysXhVh.mjs +95 -0
  14. package/dist/chunks/duotone-DWysXhVh.mjs.map +1 -0
  15. package/dist/chunks/{index-CqkX2ds2.cjs → index-BSzP10Mk.cjs} +1211 -712
  16. package/dist/chunks/index-BSzP10Mk.cjs.map +1 -0
  17. package/dist/chunks/{index-BBr7KDrd.mjs → index-C5yf_PW0.mjs} +1231 -732
  18. package/dist/chunks/index-C5yf_PW0.mjs.map +1 -0
  19. package/dist/chunks/light-CewGh2Ah.cjs +95 -0
  20. package/dist/chunks/light-CewGh2Ah.cjs.map +1 -0
  21. package/dist/chunks/light-DtApNkwW.mjs +95 -0
  22. package/dist/chunks/light-DtApNkwW.mjs.map +1 -0
  23. package/dist/chunks/{session-DBA9iE_n.mjs → session-CKOlYafG.mjs} +391 -33
  24. package/dist/chunks/session-CKOlYafG.mjs.map +1 -0
  25. package/dist/chunks/{session-DAl8n0Eh.cjs → session-DhajXqvC.cjs} +391 -33
  26. package/dist/chunks/session-DhajXqvC.cjs.map +1 -0
  27. package/dist/chunks/thin-Ccq8qzb_.mjs +95 -0
  28. package/dist/chunks/thin-Ccq8qzb_.mjs.map +1 -0
  29. package/dist/chunks/thin-Dlw1Y57w.cjs +95 -0
  30. package/dist/chunks/thin-Dlw1Y57w.cjs.map +1 -0
  31. package/dist/index.cjs +3 -3
  32. package/dist/index.mjs +20 -20
  33. package/dist/types/app/components/call/Call.vue.d.ts +1 -2
  34. package/dist/types/app/components/call/Call.vue.d.ts.map +1 -1
  35. package/dist/types/app/components/call/CallIcon.vue.d.ts +4 -0
  36. package/dist/types/app/components/call/CallIcon.vue.d.ts.map +1 -1
  37. package/dist/types/app/components/call/CallParticipants.vue.d.ts +14 -0
  38. package/dist/types/app/components/call/CallParticipants.vue.d.ts.map +1 -0
  39. package/dist/types/app/components/call/CallTile.vue.d.ts +46 -0
  40. package/dist/types/app/components/call/CallTile.vue.d.ts.map +1 -0
  41. package/dist/types/app/components/call/tokens.d.ts +204 -0
  42. package/dist/types/app/components/call/tokens.d.ts.map +1 -0
  43. package/dist/types/app/components/chat/ChatInput.vue.d.ts.map +1 -1
  44. package/dist/types/app/components/chat/ChatPageBar.vue.d.ts.map +1 -1
  45. package/dist/types/app/components/chat/chat-input/InputAttachement.vue.d.ts.map +1 -1
  46. package/dist/types/app/components/chat/contact/ContactAvatar.vue.d.ts.map +1 -1
  47. package/dist/types/app/components/general/IconButton.vue.d.ts +1 -1
  48. package/dist/types/app/components/general/IconButton.vue.d.ts.map +1 -1
  49. package/dist/types/app/components/global/BEmojiPicker.vue.d.ts +11 -4
  50. package/dist/types/app/components/global/BEmojiPicker.vue.d.ts.map +1 -1
  51. package/dist/types/app/components/global/BIcon.vue.d.ts +1 -1
  52. package/dist/types/app/components/global/BIcon.vue.d.ts.map +1 -1
  53. package/dist/types/app/components/global/emoji/data.d.ts +13 -0
  54. package/dist/types/app/components/global/emoji/data.d.ts.map +1 -0
  55. package/dist/types/app/components/global/emoji/types.d.ts +12 -0
  56. package/dist/types/app/components/global/emoji/types.d.ts.map +1 -0
  57. package/dist/types/app/components/global/icons/bold.d.ts.map +1 -1
  58. package/dist/types/app/components/global/icons/duotone.d.ts.map +1 -1
  59. package/dist/types/app/components/global/icons/fill.d.ts.map +1 -1
  60. package/dist/types/app/components/global/icons/light.d.ts.map +1 -1
  61. package/dist/types/app/components/global/icons/regular.d.ts.map +1 -1
  62. package/dist/types/app/components/global/icons/thin.d.ts.map +1 -1
  63. package/dist/types/app/composables/call/limits.d.ts +18 -0
  64. package/dist/types/app/composables/call/limits.d.ts.map +1 -0
  65. package/dist/types/app/composables/call/peer.d.ts +14 -1
  66. package/dist/types/app/composables/call/peer.d.ts.map +1 -1
  67. package/dist/types/app/composables/call/peers.d.ts +22 -3
  68. package/dist/types/app/composables/call/peers.d.ts.map +1 -1
  69. package/dist/types/app/composables/call/session.d.ts +55 -7
  70. package/dist/types/app/composables/call/session.d.ts.map +1 -1
  71. package/dist/types/app/composables/call/signaling.d.ts +23 -6
  72. package/dist/types/app/composables/call/signaling.d.ts.map +1 -1
  73. package/dist/types/app/composables/call/useCallLayout.d.ts +38 -0
  74. package/dist/types/app/composables/call/useCallLayout.d.ts.map +1 -0
  75. package/dist/types/app/composables/call/useCallNotices.d.ts +23 -0
  76. package/dist/types/app/composables/call/useCallNotices.d.ts.map +1 -0
  77. package/dist/types/app/composables/call/useCallUi.d.ts +3 -0
  78. package/dist/types/app/composables/call/useCallUi.d.ts.map +1 -1
  79. package/dist/types/app/composables/chat/useChatRecording.d.ts +1 -1
  80. package/dist/types/app/composables/useCall.d.ts +12 -1
  81. package/dist/types/app/composables/useCall.d.ts.map +1 -1
  82. package/dist/types/app/composables/useHostI18n.d.ts +1 -1
  83. package/dist/types/app/composables/useHostI18n.d.ts.map +1 -1
  84. package/dist/types/app/index.d.ts +2 -2
  85. package/dist/types/app/index.d.ts.map +1 -1
  86. package/dist/types/app/stores/callStore.d.ts +207 -24
  87. package/dist/types/app/stores/callStore.d.ts.map +1 -1
  88. package/dist/types/app/types/index.d.ts +26 -1
  89. package/dist/types/app/types/index.d.ts.map +1 -1
  90. package/dist/types/app/utils/avatar.d.ts +25 -0
  91. package/dist/types/app/utils/avatar.d.ts.map +1 -0
  92. package/dist/types/i18n/locales/index.d.ts +146 -0
  93. package/dist/types/i18n/locales/index.d.ts.map +1 -1
  94. package/package.json +6 -4
  95. package/dist/chunks/Call-B8Po7lDD.mjs +0 -1155
  96. package/dist/chunks/Call-B8Po7lDD.mjs.map +0 -1
  97. package/dist/chunks/Call-Cz-Hk_YZ.cjs +0 -1155
  98. package/dist/chunks/Call-Cz-Hk_YZ.cjs.map +0 -1
  99. package/dist/chunks/duotone-DEZDBwbj.mjs +0 -90
  100. package/dist/chunks/duotone-DEZDBwbj.mjs.map +0 -1
  101. package/dist/chunks/duotone-Dx8FFD3-.cjs +0 -90
  102. package/dist/chunks/duotone-Dx8FFD3-.cjs.map +0 -1
  103. package/dist/chunks/index-BBr7KDrd.mjs.map +0 -1
  104. package/dist/chunks/index-CqkX2ds2.cjs.map +0 -1
  105. package/dist/chunks/light-BdqG_1xJ.mjs +0 -90
  106. package/dist/chunks/light-BdqG_1xJ.mjs.map +0 -1
  107. package/dist/chunks/light-DWwZlbLY.cjs +0 -90
  108. package/dist/chunks/light-DWwZlbLY.cjs.map +0 -1
  109. package/dist/chunks/session-DAl8n0Eh.cjs.map +0 -1
  110. package/dist/chunks/session-DBA9iE_n.mjs.map +0 -1
  111. package/dist/chunks/thin-BzrijWaM.cjs +0 -90
  112. package/dist/chunks/thin-BzrijWaM.cjs.map +0 -1
  113. package/dist/chunks/thin-CXKKNj_8.mjs +0 -90
  114. package/dist/chunks/thin-CXKKNj_8.mjs.map +0 -1
package/README.md CHANGED
@@ -20,6 +20,7 @@ A drop-in Vue 3 chat and video-call UI. You supply the backend through a few han
20
20
  - [Read receipts](#read-receipts)
21
21
  - [Calls outside the chat page](#calls-outside-the-chat-page)
22
22
  - [Joining a call in progress](#joining-a-call-in-progress)
23
+ - [Group calls](#group-calls)
23
24
  - [Fake backend](#fake-backend)
24
25
  - [What `createChat()` does](#what-createchat-does)
25
26
  - [Exports](#exports)
@@ -199,6 +200,24 @@ callStore.observeCall(message, conversationId);
199
200
 
200
201
  `conversationId` can be left out for messages that carry `payload.channel`. Messages from the signed-in user are ignored. A host that never calls `observeCall` keeps the start-call buttons.
201
202
 
203
+ ### Group calls
204
+
205
+ A call on a group conversation can have several people in it, each connected directly to every other one. Calls are capped at **4 participants**, counting each device or tab, so mid-range phones can carry everyone's video. A host can lower the cap (never below 2):
206
+
207
+ ```ts
208
+ createChat({ call: { ...handlers, maxParticipants: 3 }, /* … */ });
209
+ ```
210
+
211
+ - **Joining a full call.** `callStore.ongoingCall(id)` returns `{ video, count, max, full }`. When `full`, the header's Join is disabled and reads "Call is full", and `startCall(id)` shows a toast instead of starting, whoever calls it. Two people joining at once into the last place can't see each other coming: every client orders the participants by when they joined, and whoever ranks past the cap leaves on their own with the same message. The people in the call notice nothing.
212
+ - **The call screen.** Alone, the user sees their own camera and "Waiting for others to join…" ("Everyone else left" once others have gone; the library never hangs up on its own). With one other person, the layout is as in 5.0. With two or three others, everyone is a tile of a 2×2 grid, which fits a 360 px phone without scrolling. A screen share, or a tile the user pins, takes the stage, with everyone else in a strip along the bottom (portrait) or the inline end (landscape; the left in RTL). Tiles show the person's name, a mic-off badge, and their initial when their camera is off. The top bar holds the conversation's name, the time and a People button that opens the participant list. Joins and leaves show as a short notice, also read out to screen readers. Minimized, the window follows whoever is speaking.
213
+ - **Bad networks.** In a group, each copy of the user's camera is capped (800 kbit/s at 3 people, 500 kbit/s at 4) and audio is sent at a higher priority, so video degrades before sound. One to one keeps the browser's defaults. A connection that drops is repaired in place (an ICE restart), and if that fails, only that one pair is rebuilt. After three failures in a row the tile says "Can't connect to …" with a **Try again** button; everyone else stays connected.
214
+
215
+ What a host has to do for group calls: nothing beyond what one-to-one calls need, as long as it passes every call message to `observeCall` (above), which the Join button counts from. Deciding when a call ends is the host's: phc-frontend, for example, ends a group call by itself only if nobody ever answered.
216
+
217
+ **Protocol.** Group calls add optional fields to existing messages and no new message types, so 5.0 clients and the earlier simple-peer builds still call this one: `join.joinedAt` and `join.to` (a reconnect aimed at one participant; older clients take it as aimed at them), `track_type.media` (`{ audio, video }`, sent on every mic or camera change) and `track_type.joinedAt`, and `presence.joinedAt`. Older clients ignore the fields, and a message without them is handled as before: no badges for that participant, and they order last for the cap.
218
+
219
+ **Test ids** for hosts' own tests, besides the existing `call-remote-video`, `call-remote-screen` and `call-local-video`: `call-top-bar`, `call-participant-count`, `call-people-button`, `call-people-list`, `call-participant` (with `data-participant-id`), `call-tile` (with `data-participant-id` and `data-kind` `camera`, `screen` or `self`), `call-tile-muted`, `call-tile-avatar`, `call-tile-unreachable`, `call-pin`, `call-notice`, `call-waiting` and `call-strip`.
220
+
202
221
  ### Fake backend
203
222
 
204
223
  `vue-parley/fakes` is an in-memory implementation of every handler, for demos, playgrounds and tests. It is a separate entry, so apps that don't import it don't ship it.
@@ -244,11 +263,11 @@ Every component and directive the chat uses is imported by the component itself,
244
263
  | `ChatPage` | The whole chat: contact list, conversation and call view. |
245
264
  | `Call` | The call view (async). |
246
265
  | `ChatList`, `ChatConversation`, `ChatHeader`, `ChatMessages`, `ChatInput`, `ChatBubble` | Building blocks for custom layouts. |
247
- | `BIcon`, `BEmojiPicker`, `BVirtualVerticalList` | A Phosphor icon by name, the emoji picker and the virtualised list the chat uses. Every other control is a PrimeVue component. |
266
+ | `BIcon`, `BEmojiPicker`, `BVirtualVerticalList` | A Phosphor icon by name (rendered by `@iconify/vue` from bundled `ph` data, so it never calls the Iconify API), the emoji picker (PrimeVue and Tailwind; its `select` event carries an `EmojiSelection`, `{ emoji, label }`) and the virtualised list the chat uses. Every other control is a PrimeVue component. |
248
267
  | `useChatStore`, `useMessagesStore`, `useMediaStore`, `useProfileStore`, `useCallStore` | The Pinia stores. |
249
268
  | `messageMedia(message)` | A message's photo and video album: its `media`, or its `imageUrl` as photos. |
250
269
  | `resetChat()` | Forgets everything the chat loaded for the signed-in user (conversations, threads, drafts, shared media, the downloaded-file cache) and ends a running call. Call it on sign-out or an account switch, before the next user's chat mounts; the handlers stay. Each store also has its own `reset()` (`clearCache()` on the media store). |
251
- | Types | Handler interfaces, `Contact`, `Message`, `MediaItem`, `SignalData`, `ChatOptions`, `ChatUser` and the rest of `app/types`. |
270
+ | Types | Handler interfaces, `Contact`, `Message`, `MediaItem`, `SignalData`, `ChatOptions`, `ChatUser`, the call's `ParticipantStatus`, `CallPhase` and `CallMediaState`, and the rest of `app/types`. |
252
271
  | `vue-parley/fakes` | `createFakeBackend`, `createBroadcastCallHandlers`, `demoData`, `e2eData`: see [Fake backend](#fake-backend). |
253
272
 
254
273
  Working with conversations the list page hasn't fetched (say, one opened from a link): add them with `chatStore.addContact(contact)` and change them with `chatStore.updateContact(id, changes)`. `chatStore.conversationStates` is a read-only view.
@@ -313,7 +332,9 @@ pnpm test:e2e # Playwright suite (test:e2e:ui for the UI runner)
313
332
 
314
333
  The demo (`demo/`, a workspace package that consumes the built `dist/`) runs on the fakes with a seeded Persian dataset. Open it in two tabs with different `?user=` values and start a call in both to try video calling.
315
334
 
316
- `pnpm test:e2e` runs the Playwright suite in `e2e/`: every chat feature against the in-memory fakes, plus real two-tab video calls using Chromium's fake camera and mic. Tests also fail if a template uses a component or directive nobody registered.
335
+ `pnpm test:e2e` runs the Playwright suite in `e2e/`: every chat feature against the in-memory fakes, plus real video calls between tabs using Chromium's fake camera and mic: one to one, with the previous simple-peer build, and groups of up to four with a fifth turned away (`e2e/tests/group-call.spec.ts`). Tests also fail if a template uses a component or directive nobody registered.
336
+
337
+ In the w3x devzone, run it in Docker instead: `./dz install vue-parley`, then `./dz run --rm vue-parley-e2e [spec]` (Microsoft's Playwright image, whose tag matches `@playwright/test`).
317
338
 
318
339
  On NixOS, use the Nix-built browsers (the nixpkgs `playwright-driver` version must match `@playwright/test`):
319
340
 
@@ -333,7 +354,8 @@ app/
333
354
  types/ handler interfaces and data types
334
355
  assets/css/ theme tokens and base styles
335
356
  i18n/locales/ en and fa translations
336
- scripts/ generate-icons.mjs: BIcon's Phosphor SVGs, one module per weight (add an icon there)
357
+ scripts/ generate-icons.mjs: BIcon's Phosphor icons from @iconify-json/ph, one module per weight (add an icon there)
358
+ generate-emoji.mjs: BEmojiPicker's emoji list from emojibase-data (rerun after bumping it)
337
359
  fakes/ in-memory backend and call handlers (published as `vue-parley/fakes`)
338
360
  demo/ demo app (workspace package)
339
361
  e2e/ Playwright tests and harness