@robono/messaging-react-native 0.2.0 → 0.3.1

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 (85) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +84 -7
  3. package/SBOM.spdx.json +1290 -234
  4. package/dist/account.d.ts +15 -0
  5. package/dist/account.js +27 -0
  6. package/dist/call-message.js +7 -1
  7. package/dist/calling.js +5 -9
  8. package/dist/conversation-details.d.ts +24 -0
  9. package/dist/conversation-details.js +83 -0
  10. package/dist/emoji-text.d.ts +2 -0
  11. package/dist/emoji-text.js +8 -0
  12. package/dist/expo-history.d.ts +3 -0
  13. package/dist/expo-history.js +59 -0
  14. package/dist/expo-media.d.ts +1 -0
  15. package/dist/expo-media.js +46 -43
  16. package/dist/expo-messenger.d.ts +35 -0
  17. package/dist/expo-messenger.js +39 -0
  18. package/dist/expo-notifications.d.ts +31 -0
  19. package/dist/expo-notifications.js +92 -0
  20. package/dist/expo-outbox.js +2 -1
  21. package/dist/expo-privacy.d.ts +4 -0
  22. package/dist/expo-privacy.js +7 -0
  23. package/dist/expo-screen.d.ts +42 -0
  24. package/dist/expo-screen.js +557 -0
  25. package/dist/expo.d.ts +2 -42
  26. package/dist/expo.js +2 -549
  27. package/dist/extras-lifecycle.d.ts +2 -0
  28. package/dist/extras-lifecycle.js +27 -0
  29. package/dist/extras.d.ts +49 -0
  30. package/dist/extras.js +49 -0
  31. package/dist/forward.js +4 -3
  32. package/dist/group-editor.d.ts +18 -0
  33. package/dist/group-editor.js +98 -0
  34. package/dist/header-calls.d.ts +18 -0
  35. package/dist/header-calls.js +45 -0
  36. package/dist/icons.d.ts +2 -0
  37. package/dist/icons.js +2 -0
  38. package/dist/inbox-search.d.ts +11 -0
  39. package/dist/inbox-search.js +42 -0
  40. package/dist/inbox.d.ts +5 -2
  41. package/dist/inbox.js +19 -15
  42. package/dist/index.d.ts +33 -3
  43. package/dist/index.js +359 -141
  44. package/dist/media-controller.d.ts +3 -0
  45. package/dist/media-controller.js +39 -0
  46. package/dist/media-ui.d.ts +14 -3
  47. package/dist/media-ui.js +90 -28
  48. package/dist/message-menu.d.ts +28 -0
  49. package/dist/message-menu.js +24 -0
  50. package/dist/message-order.d.ts +3 -0
  51. package/dist/message-order.js +10 -0
  52. package/dist/messenger-video-view.d.ts +8 -0
  53. package/dist/messenger-video-view.js +46 -0
  54. package/dist/native-outbox.d.ts +8 -2
  55. package/dist/native-outbox.js +3 -1
  56. package/dist/photo-gesture.d.ts +20 -0
  57. package/dist/photo-gesture.js +52 -0
  58. package/dist/polls.d.ts +2 -1
  59. package/dist/polls.js +19 -17
  60. package/dist/popup.d.ts +43 -1
  61. package/dist/popup.js +72 -6
  62. package/dist/quick-send.d.ts +15 -0
  63. package/dist/quick-send.js +26 -0
  64. package/dist/safety.d.ts +9 -1
  65. package/dist/safety.js +21 -6
  66. package/dist/saved.d.ts +1 -1
  67. package/dist/saved.js +9 -4
  68. package/dist/search.d.ts +2 -2
  69. package/dist/search.js +32 -14
  70. package/dist/social.d.ts +9 -3
  71. package/dist/social.js +11 -15
  72. package/dist/translation-settings.d.ts +12 -0
  73. package/dist/translation-settings.js +16 -0
  74. package/dist/use-quote-gesture.d.ts +5 -1
  75. package/dist/use-quote-gesture.js +35 -17
  76. package/dist/visual/WeatherArtwork.d.ts +9 -0
  77. package/dist/visual/WeatherArtwork.js +43 -0
  78. package/dist/visual/weather-artwork.d.ts +17 -0
  79. package/dist/visual/weather-artwork.js +86 -0
  80. package/dist/visual/weather-conditions.d.ts +5 -0
  81. package/dist/visual/weather-conditions.js +2 -0
  82. package/dist/voice-composer.js +2 -2
  83. package/dist/voice-waveform.d.ts +2 -0
  84. package/dist/voice-waveform.js +21 -0
  85. package/package.json +24 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,60 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.1 — 2026-11-03
4
+
5
+ Match Messenger’s bottom communication tools: keep the surrounding area on the chat background, place attachment/text/microphone controls inside one rounded field, and keep Send or the quick reaction outside it. Apply the same neutral field to recording and voice-only mode.
6
+
7
+ ## 0.3.0 — 2026-11-03
8
+
9
+ Add the complete ExpoMessenger setup and supplied inbox search, contact/shared-media, group owner, replies and pinned-message screens. Reuse Messenger popup boundaries and composer. Add opt-in native Apple/Google notification registration with account-safe logout, and expiring local received history. Notification credentials remain on the customer server.
10
+
11
+ Requires matching service migrations 181–186 and coordinated package publication. Physical-device notification delivery is a separate acceptance check.
12
+
13
+
14
+ Correct navigation scope: Saved is in the account-level Messages menu, not the contact menu. Search this chat uses an inline bar with previous/next matches. The native inbox has separate chat-list search and retains media adapters when opening Saved.
15
+
16
+ Refine popup interiors with grouped Saved/Search rows, aligned translation controls, consistent form fields, a subtle header divider, and a readable content width on desktop. Preserve the approved app-height black frame and existing translation behavior.
17
+
18
+ Use one Messenger popup frame and title/X row across search, contact options, Saved, forwarding, polls, confirmations, weather, tracking and social previews. Use the same app-height, black frame, raised title/X, and narrow 0/8/4/8 inner spacing as tracking/social, including forms and confirmations. Keep the frame inside phone safe areas. Keep inbox actions and delete confirmation in the same modal.
19
+
20
+ Move Saved from a standalone header bookmark into its own three-dot menu entry, matching Messenger’s Saved navigation. Dismiss the options modal before opening Saved on iOS.
21
+
22
+ When Privacy Lens is enabled, place messages above the clear reading strip. Keep short chats scrollable into the strip and leave new arrivals above it until the user scrolls.
23
+
24
+ Tighten Yes/No bubbles to content width, with an inline poll icon and compact answer row. Give polls an outlined neutral card and remove inline timestamps; time remains in the swipe details.
25
+
26
+ Show Messenger’s condition-specific weather artwork for current, hourly and daily forecasts, using compact inline icons.
27
+
28
+ Expand weather to the same safe-area popup as tracking and social, with the raised header and dark backdrop. Let forecast content scroll within the available space.
29
+
30
+ Circle the centered latest-message arrow. Fade it out during scrolling and restore it after a 600ms pause when still away from the latest message.
31
+
32
+ Preserve independently consented address shares while moving between chats or the inbox. Stop only the selected share when End tracking is pressed; app background/logout still stop capture.
33
+
34
+ Place social-share Preview buttons beside the bubble and omit inline timestamps. Use the expanded safe-area popup, dark backdrop and raised header shared with tracking; let the social player fill available space.
35
+
36
+ Keep the sharing button and single avatar row within the measured address-bubble height.
37
+
38
+ Enlarge tracking names, speed/distance and ETA details. Pass the selected units and current time to map adapters so participant callouts stay synchronized.
39
+
40
+ Keep the expanded tracking popup within native safe areas. Size the map from the remaining popup space, with compact controls and a bounded scrolling participant list.
41
+
42
+ Expand live tracking to an inset app-sized popup. Add 48-point circular participant avatar buttons below the sharing control; tapping an avatar opens the map with that person selected.
43
+
44
+ Open live tracking from the full address-bubble body while keeping the address link and sharing button separate. Darken the shared popup backdrop to 85% black.
45
+
46
+ Keep city, state and ZIP in address links when the street is not followed by a comma. Reduce address-bubble vertical padding.
47
+
48
+ Tighten address bubbles: place a compact outlined “Allow tracking” button with a location icon beside the bubble toward the center of the chat, omit the empty participant row, and show the time only in the swipe information reveal.
49
+
50
+ Place enabled Camera capture inside Attach beside the photo/video library options, matching Messenger. Keep it available when library browsing is hidden, and stage captured media before Send.
51
+
52
+ Fix photo pinch-to-zoom and panning: Messenger’s 1–5× range, actual image bounds, smooth transitions when fingers join/leave, and no accidental toolbar toggle after a gesture. Support browser touch and trackpad pinch.
53
+
54
+ Match Messenger’s information/quote swipe travel and return timing; reveal sent/read information behind ordinary bubbles. Remove photo/video timestamp overlays and redundant sent/read checkmarks.
55
+
56
+ Select multiple photos, videos or files in one picker visit, preserving order, draft thumbnails, the remaining ten-file limit, and local-until-Send behavior. Keep editing/call replies single-file. Preserve pending attachments when a host recreates its preview callback while typing. Use Messenger’s full reaction catalogue.
57
+
3
58
  ## 0.2.0
4
59
 
5
60
  Use the compact Messenger media toolbar, autoplay video after audio setup, and offer native full-screen playback. Dismiss iOS menus before presenting Saved media, Forward/Delete/Report or Search; keep native pickers free of a competing modal. Reserve the actual timestamp width so edited messages do not overlap it.
package/README.md CHANGED
@@ -1,6 +1,43 @@
1
1
  # Optional Robono messaging screens
2
2
 
3
- Use a ready-made direct or group conversation screen, replace its sections, or compose the exported components into your own layout. This package is optional and adds no navigation, global audio configuration or push handlers to your app. The shared icon controls require `react-native-svg` (install it with your framework’s native dependency installer).
3
+ Use a ready-made direct or group conversation screen, replace its sections, or compose the exported components into your own layout. Use `ExpoMessenger` for the complete inbox and conversation flow, or the individual components inside your existing navigation. Notification registration is explicit; nothing requests permission on mount. The shared icon controls require `react-native-svg` (install it with your framework’s native dependency installer).
4
+
5
+ ## Recommended installation
6
+
7
+ Connect `createRobonoMessengerServer` from `@robono/server` at one authenticated
8
+ HTTPS route. It supplies managed private attachments. Create one connection per
9
+ signed-in account, outside repeated renders:
10
+
11
+ ```tsx
12
+ import {createExpoMessenger, ExpoMessenger} from '@robono/messaging-react-native/expo';
13
+ const messenger = createExpoMessenger({
14
+ endpoint: 'https://your-app.example/api/robono',
15
+ userId: session.userId,
16
+ getAccessToken: () => session.accessToken(),
17
+ isCallActive: () => calls.isActive(),
18
+ });
19
+ <ExpoMessenger {...messenger} userId={session.userId}
20
+ companyName="Your company" contacts={contacts} />
21
+ // On logout, before destroying the user's session:
22
+ try { await messenger.signOut(); } finally { await session.signOut(); }
23
+ ```
24
+
25
+ Install the native dependencies below and rebuild both platforms. For alerts
26
+ outside the app, use the explicit `./expo-notifications` connector and follow
27
+ `@robono/server/NOTIFICATIONS.md`: iPhone needs **your** Apple Team ID, APNs Key ID,
28
+ private .p8 key and Bundle ID; Android needs **your** Firebase project, app
29
+ configuration and a server-only service account. Never ship private keys in the
30
+ app. Website chat itself does not require these mobile credentials.
31
+
32
+ The supplied group owner, shared-media, reply and pinned-message screens use the
33
+ same popup boundaries as Messenger. Global search and group controls require the
34
+ matching server and service migrations. Imported groups need a server-assigned
35
+ owner before users can edit them. Optional offline received history is disabled
36
+ by default; its network-selected expiry is honored and it is read-only offline.
37
+ Revocation while disconnected is not known until reconnection or expiry. Logout
38
+ clears the local account's history. `persistence:false` disables these local stores.
39
+
40
+ ## Individual screen inside existing navigation
4
41
 
5
42
  ```tsx
6
43
  import {MessagingScreen} from '@robono/messaging-react-native';
@@ -27,7 +64,7 @@ Text uses a send icon; `appearance.labels.send` remains its accessible label. Vo
27
64
 
28
65
  Supply `attachmentPreview(message)` to resolve `{uri?, waveform?}` after checking the current user's media access. `uri` is an image thumbnail (a poster frame for video); `waveform` contains 32 normalized amplitude values between 0 and 1. These stay in component state, not in the message payload. Without metadata the SDK shows a neutral media tile or waveform track. `openAttachment` remains responsible for authorized media access. The Expo screen supplies inline voice playback and the shared full-screen media viewer. To connect a different audio engine, supply `components.VoiceMessage` and render the exported `VoicePlayback` with its playback state and callbacks. `MediaViewer`, `ZoomablePhoto` and `MediaPlaybackControls` are also exported for hosts with their own media engines.
29
66
 
30
- Photos, videos and files share an Attach menu. Set `appearance.showCamera` to offer Camera alongside them; photo messaging must also be enabled. The option defaults off for existing integrations. Camera calls `pickAttachment('image', {...limits, source: 'camera'})`, so captures follow the same photo restrictions and review/upload process. Hosts supplying their own media callback must handle that source explicitly. The Expo adapter requests camera permission only on selection and opens the device camera on iOS and Android. Configure the `expo-image-picker` plugin's `cameraPermission` explanation in your native build. Cancelling or refusing permission sends nothing.
67
+ Photos, videos and files share an Attach menu. Set `appearance.showCamera` to offer Camera inside that menu beside the library options; photo or video messaging must also be enabled. The option defaults off for existing integrations. Camera calls `pickAttachment('image', {...limits, source: 'camera'})`, so captures follow the same photo restrictions and review/upload process. Hosts supplying their own media callback must handle that source explicitly. The Expo adapter requests camera permission only on selection and opens the device camera on iOS and Android. Configure the `expo-image-picker` plugin's `cameraPermission` explanation in your native build. Cancelling or refusing permission sends nothing.
31
68
 
32
69
  ## Reuse or replace components
33
70
 
@@ -144,7 +181,7 @@ The standard chat uses compact grouped bubbles, timestamps at the lower right, i
144
181
 
145
182
  Voice-only conversations use Robono Messenger’s compact composer: the duration-limit placeholder, embedded microphone and adjacent Send control. The Expo adapter records and reviews audio inline, with elapsed time, microphone metering, playback and removal before sending. The builder uses the same controls with a local browser microphone recording; no audio is uploaded from the preview. When texting is enabled, tap the microphone to record in the composer and tap it again to stop. Each completed recording becomes a separate playable attachment in the shared horizontal row, and the microphone is available for another recording. Typed text is preserved; Send puts accompanying text on the last attachment as its caption. Custom media adapters can use `components.VoiceComposer`, `VoiceMessageComposer` and `VoiceDraftPlayback`; `renderTextComposer` restores the text controls alongside the reviewed recording.
146
183
 
147
- Recent attachments can appear directly beneath the attachment buttons. Photos, Videos and Document filter this strip; tapping the selected category again shows all enabled types. Tapping a thumbnail adds it above the composer as a pending attachment; its magnifying-glass button opens a preview instead. Remove unwanted attachments or press Send to submit the selection with any typed text. Camera starts capture. When no recent-media source is supplied, the category buttons open the device picker. Supply `attachmentChoices` with an ID, kind, name, and optional thumbnail URI/duration. Only enabled attachment types appear. With `MessagingScreen`, selecting a tile calls `pickAttachment` with `options.attachmentId`; use `options.intent` to distinguish selection (`send`, retained for adapter compatibility) from preview. Returning photo, video or document media stages it in the composer; returning null cancels without selecting it. Voice recordings also become pending attachments after recording stops. With `ExpoMessagingScreen`, supply `resolveAttachmentChoice(id, signal)` to return an authorized cache copy; the standard preview, validation, send and cleanup flow handles the rest. Keep originals in the user's library untouched. The host controls library access and which recent items it supplies.
184
+ Recent attachments can appear directly beneath the attachment buttons. Photos, Videos and Files filter this strip; tapping the selected category again shows all enabled types. Tapping a thumbnail adds it above the composer as a pending attachment; its magnifying-glass button opens a preview instead. Remove unwanted attachments or press Send to submit the selection with any typed text. Camera starts capture. When no recent-media source is supplied, the category buttons open the device picker. Supply `attachmentChoices` with an ID, kind, name, and optional thumbnail URI/duration. Only enabled attachment types appear. With `MessagingScreen`, selecting a tile calls `pickAttachment` with `options.attachmentId`; use `options.intent` to distinguish selection (`send`, retained for adapter compatibility) from preview. Returning photo, video or document media stages it in the composer; returning null cancels without selecting it. Voice recordings also become pending attachments after recording stops. With `ExpoMessagingScreen`, supply `resolveAttachmentChoice(id, signal)` to return an authorized cache copy; the standard preview, validation, send and cleanup flow handles the rest. Keep originals in the user's library untouched. The host controls library access and which recent items it supplies.
148
185
 
149
186
  Camera capture and library selection are separate controls. `appearance.showPhotoLibrary` and `showVideoLibrary` hide library choices without removing the corresponding message-type permission needed for camera captures. Both default to true for existing integrations. The builder manages these together with Camera, so enabling capture does not select Photos/Videos or insert example media. Parent and network message-type permissions remain enforced.
150
187
 
@@ -165,11 +202,11 @@ Use `ExpoMessagingCallingScreen` from `@robono/messaging-react-native/expo-calli
165
202
 
166
203
  ### Blocking, reporting, reactions and language tools
167
204
 
168
- The default header’s three-dot menu provides Block/Unblock and Report when the authenticated backend advertises safety support. Hold a received bubble to report that message. `onContactOptions` optionally replaces the supplied contact menu with your existing safety flow. The exported `MessagingSafety` component can also be composed into your screen.
205
+ The conversation header’s three-dot menu includes Search this chat, plus Block/Unblock and Report when the authenticated backend advertises safety support. Saved belongs to the account and is in the separate Messages menu, never under a contact’s name. Hold a received bubble to report that message. `onContactOptions` optionally replaces the supplied contact menu with your existing safety flow. The exported `MessagingSafety` component can also be composed into your screen.
169
206
 
170
207
  Blocking retains history and stops direct messages and calls for that pair in your app. Shared group messages remain visible. Reporting is separate: it shares the selected message, or up to five recent incoming messages, and the reason with your app’s moderators. It confirms success only after storage acknowledges the report. The SDK reuses the request ID on retry. Owners and administrators review reports in the Messaging workspace; private media is reviewed through your app’s authorized storage tools.
171
208
 
172
- Enable Reactions to show an emoji ribbon beside the long-pressed bubble, or the hover smile icon on desktop. Selected reactions stay attached below the message. Polls are interactive chat messages created from the attachment menu. Transcript shows readable text under a voice message. Translate opens the shared compact popup with **Translate to text** and **Translate to voice**. Both text and voice messages support either output. The Expo screen supplies the spoken-result player and uses the normal audio session, so recordings and other playback do not overlap. The original message and timestamp stay in place. Provide `language` for the viewer’s target language and connect `MessagingClient.transformRequest` to the authenticated `createMessagingTransformBackendAdapter` on your server.
209
+ Enable Reactions to show an emoji ribbon beside the long-pressed bubble, or the hover smile icon on desktop. Selected reactions stay attached below the message. Polls are interactive chat messages created from the attachment menu. Transcript is a separate voice-message action. In the header's three-dot menu, choose translation **Off / Text / Voice** and languages once for the conversation. The saved choice controls Translate or Play Translation on eligible incoming messages; own messages and matching sender/target languages do not show it. The result has Show original / Show translation controls. Expo supplies translated-voice playback and its audio session; an explicit Play Translation action starts playback when ready. `language` supplies the initial target and `contact.language` / `participants[id].language` supply known sender languages, with a saved conversation incoming-language fallback. Defaults to Off. The Expo private outbox retains preferences across restarts on this device. Custom contact menus can call `client.setTranslationPreference({mode:'text',language:'es',sourceLanguage:'en'})`. Connect `MessagingClient.transformRequest` to the authenticated `createMessagingTransformBackendAdapter` on your server.
173
210
 
174
211
  ### November 1 behavior update (unpublished)
175
212
 
@@ -189,7 +226,7 @@ in `media.waveform`. The playback track remains seekable when the waveform is
189
226
  hidden. Managed storage computes waveform data independently of this preference.
190
227
 
191
228
  Groups offer polls; direct chats offer a recipient-only Yes/No question whose
192
- first answer is final. Both use centered popups on all platforms. Deploy migration
229
+ first answer is final. Both use the same app-height popup frame as tracking and social previews. Deploy migration
193
230
  `20261101017400_messaging_captions_questions.sql` and the updated messaging handler
194
231
  before releasing these SDK changes. Deploy the updated media inspector before the
195
232
  updated managed-media handler. These source changes have not been published.
@@ -232,10 +269,50 @@ Updated backend support is required; old adapters hide these controls.
232
269
 
233
270
  Long press a message, then choose Select to select more rows. The compact action bar supports chronological forwarding and deletion of eligible unread outgoing messages. A single selection also supports Copy, Save and Edit. Back clears the selection.
234
271
 
235
- `createExpoMessagingClient` also supplies Saved: explicit local text and attachment copies in the app-private directory, separated by endpoint, account and namespace. The shared header opens Saved. Saving rechecks message access before and after making the copy, and marks incoming content consumed. Saved copies are independent of network retention; they never reuse signed URLs. `client.signOut()` deletes this account’s saved copies. Disabling persistence also disables Saved. Device storage is not a cloud backup or an additional app encryption layer. For a custom engine, supply a `MessagingSavedStore` to `MessagingClient` and `openSavedAttachment` to the shared screen.
272
+ `createExpoMessagingClient` also supplies Saved: explicit local text and attachment copies in the app-private directory, separated by endpoint, account and namespace. The account-level Messages menu opens Saved from all conversations. Standalone chats have no account toolbar; place account navigation on the host inbox. For inbox navigation, keep one `MessagingProvider` mounted around `MessagingConversation` / `MessagingInbox` and pass `headerActions={<MessagingAccountMenu/>}` to the inbox; the Expo `renderConversation` callback supplies the same media adapters to that provider. Saving rechecks message access before and after making the copy, and marks incoming content consumed. Saved copies are independent of network retention; they never reuse signed URLs. `client.signOut()` deletes this account’s saved copies. Disabling persistence also disables Saved. Device storage is not a cloud backup or an additional app encryption layer. For a custom engine, supply a `MessagingSavedStore` to `MessagingClient` and `openSavedAttachment` to the shared screen.
236
273
 
237
274
  ### Social previews
238
275
 
239
276
  Install `react-native-webview` with the Expo peer dependencies and rebuild the native app. `ExpoMessagingScreen` supplies the player and the standard shared popup; a custom engine can supply `components.SocialPlayer`. The updated server adapter and hosted messaging endpoint advertise support. Recognized links gain a small play action, while tapping the link still opens the original app/site. Players are loaded only after an explicit tap and fresh message authorization, require explicit playback, and are removed on close/background/navigation. Opening a player stops the current voice-message player and uses the supplied audio-session coordinator. No application cookies or local-file access are shared with the embedded page. Some providers/private posts cannot be embedded; the popup keeps an Open-original link.
240
277
 
241
278
  The same provider parser is used by Messenger, the browser and the backend, including Snapchat and Rumble. Preview opens contribute to the per-network `social.opened` metric. This source change still requires coordinated endpoint and package deployment; installing a newer UI against an older adapter does not enable unsupported controls.
279
+
280
+
281
+ ### Multiple selections from one picker
282
+
283
+ The supplied Expo and browser pickers allow selecting several photos, videos, or
284
+ files in one visit, up to ten total pending attachments. Selection stays local:
285
+ each item has a removable thumbnail, preview is a separate tap, and upload begins
286
+ only after Send. Order is preserved, the quote belongs to the first attachment,
287
+ and the caption belongs to the last. Editing and call replies select one item.
288
+
289
+ A custom `pickAttachment(kind, options)` may return one `MessageMedia`, an ordered
290
+ `MessageMedia[]`, or `null`. Honor `options.maxCount` (the remaining slots) and the
291
+ existing size/type/duration limits. Existing single-file adapters still work.
292
+ The low-level `MessagingMediaDevice.pickMany` method is optional;
293
+ `MessagingMediaController.pickMany` falls back to the single picker when absent.
294
+ Cancellation or an invalid selection releases all private copies without sending
295
+ or accepting a partial batch. Never delete the user's library originals.
296
+
297
+ Conversation search stays inline below the chat header with a match count and previous/next controls. Its authenticated search remains scoped to the open conversation. `MessagingInbox` provides a separate Search chats field over loaded chat titles and last-message text; optional `searchText(row)` adds the host's local retained-message index (used in the native review). It does not imply a server-wide search across unloaded conversations.
298
+
299
+ ### Company, account and call controls
300
+
301
+ `companyName` is the customer’s company name, not Robono’s. It labels the inbox
302
+ only; when omitted, the configured appearance name is used. Conversation screens
303
+ show only the friend/group header, never the company heading or account menu.
304
+ The main three-dot dropdown contains Account and Saved. Supply `account` with
305
+ `name`, optional `avatarUrl`, `phone`, and `email`. `onEditProfile` and `onSignOut`
306
+ are optional host actions; unsupported actions are hidden. Sign-out must revoke
307
+ your app session and call the messaging client’s `signOut()` to clear local data.
308
+ The Account screen dismisses before opening the host’s profile/sign-out flow.
309
+
310
+ Direct conversations keep the customer’s accent header. Groups use Messenger’s
311
+ blue `#1F5F7A` header with light text and icons. Phone/video icons use the same ink.
312
+ Supply `callActions.voice`/`video` only while the contact/group is eligible for
313
+ those calls. `callActions.phoneNumber` supplies a direct contact’s callable number,
314
+ and `callActions.phone(number)` can override opening the system `tel:` handler.
315
+ The phone button opens Messenger’s method choices when a number exists; otherwise
316
+ it starts the available internet call directly. Groups never show a carrier choice.
317
+ `MessagingCallingScreen` and `ExpoMessagingCallingScreen` still accept existing
318
+ `onCall`/`onVideoCall` callbacks and use these same controls.