@marktiderman/genesis-chat 0.2.2 → 0.3.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 (37) hide show
  1. package/README.md +119 -6
  2. package/dist/{chunk-VEPZROQB.js → chunk-BTG4JWLF.js} +5 -4
  3. package/dist/chunk-BTG4JWLF.js.map +1 -0
  4. package/dist/{chunk-AZS3HNLM.js → chunk-IEFULAC2.js} +25 -3
  5. package/dist/chunk-IEFULAC2.js.map +1 -0
  6. package/dist/{chunk-JU2FAPBI.js → chunk-XQ2ULNHV.js} +2 -2
  7. package/dist/{chunk-JU2FAPBI.js.map → chunk-XQ2ULNHV.js.map} +1 -1
  8. package/dist/native.d.ts +158 -6
  9. package/dist/native.js +404 -181
  10. package/dist/native.js.map +1 -1
  11. package/dist/push.d.ts +2 -1
  12. package/dist/push.js +1 -1
  13. package/dist/react.d.ts +6 -2
  14. package/dist/react.js +1 -1
  15. package/dist/server.js +1 -1
  16. package/dist/web.d.ts +6 -2
  17. package/dist/web.js +6 -18
  18. package/dist/web.js.map +1 -1
  19. package/package.json +9 -9
  20. package/src/native/__tests__/attachment-slot.test.tsx +353 -0
  21. package/src/native/__tests__/organise-screens.test.tsx +12 -0
  22. package/src/native/__tests__/push-ids.test.ts +18 -0
  23. package/src/native/__tests__/push.test.ts +10 -4
  24. package/src/native/attachment-cards.tsx +249 -11
  25. package/src/native/copy.ts +15 -0
  26. package/src/native/index.ts +28 -4
  27. package/src/native/media.tsx +89 -2
  28. package/src/native/message-bubble.tsx +78 -12
  29. package/src/native/push.ts +5 -2
  30. package/src/native/search-screen.tsx +77 -69
  31. package/src/native/thread-screen.tsx +23 -6
  32. package/src/react/error-boundary.tsx +46 -0
  33. package/src/react/index.tsx +6 -2
  34. package/src/web/cards.tsx +2 -2
  35. package/src/web/error-boundary.tsx +2 -30
  36. package/dist/chunk-AZS3HNLM.js.map +0 -1
  37. package/dist/chunk-VEPZROQB.js.map +0 -1
package/dist/push.d.ts CHANGED
@@ -31,7 +31,8 @@ import '@supabase/supabase-js';
31
31
 
32
32
  declare const CHAT_PUSH_CATEGORY = "messages";
33
33
  declare const CHAT_REPLY_ACTION = "reply";
34
- declare const CHAT_MARK_READ_ACTION = "mark-read";
34
+ /** The same id as genesis-notifications' `MESSAGE_ACTIONS` (device ids take no "-" or ":"). */
35
+ declare const CHAT_MARK_READ_ACTION = "mark_read";
35
36
  interface ChatPushCopy {
36
37
  title: string;
37
38
  description: string;
package/dist/push.js CHANGED
@@ -1,3 +1,3 @@
1
- export { CHAT_MARK_READ_ACTION, CHAT_PUSH_CATEGORY, CHAT_REPLY_ACTION, PUSH_REPLY_WAIT_MS, chatNotificationActions, chatPath, chatPushCategory, chatPushCopy, chatPushPayload, chatThreadMatch, conversationIdFromData, failedReply, handleChatPushResponse, registerChatNotificationActions, replyClientId, replyClientIdFor } from './chunk-VEPZROQB.js';
1
+ export { CHAT_MARK_READ_ACTION, CHAT_PUSH_CATEGORY, CHAT_REPLY_ACTION, PUSH_REPLY_WAIT_MS, chatNotificationActions, chatPath, chatPushCategory, chatPushCopy, chatPushPayload, chatThreadMatch, conversationIdFromData, failedReply, handleChatPushResponse, registerChatNotificationActions, replyClientId, replyClientIdFor } from './chunk-BTG4JWLF.js';
2
2
  //# sourceMappingURL=push.js.map
3
3
  //# sourceMappingURL=push.js.map
package/dist/react.d.ts CHANGED
@@ -65,11 +65,15 @@ interface ChatCardContext {
65
65
  interface ChatAttachmentKind {
66
66
  title(attachment: ChatAttachment, ctx?: ChatCardContext): string;
67
67
  subtitle?(attachment: ChatAttachment, ctx?: ChatCardContext): string | null | undefined;
68
- /** The card's button: a link (`href`) or a handler (`onPress`). */
68
+ /**
69
+ * The card's button: a link (`href`) or a handler (`onPress`). On native the button is also the
70
+ * bubble's VoiceOver action, and a handler that returns a promise shows the card as busy until
71
+ * it settles (and a short error if it rejects).
72
+ */
69
73
  action?(attachment: ChatAttachment, ctx?: ChatCardContext): {
70
74
  label: string;
71
75
  href?: string;
72
- onPress?: () => void;
76
+ onPress?: () => void | Promise<unknown>;
73
77
  } | null | undefined;
74
78
  /** What previews call it (the inbox's last message, "Check-in"); the title by default. */
75
79
  label?: string;
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- export { CATCH_UP_MAX_PAGES, CATCH_UP_PAGE, ChatProvider, LINK_PREVIEW_CONCURRENCY, belongsTo, chatKeys, hostedUploadFrom, useAvailability, useBroadcast, useChat, useConversation, useDebouncedValue, useFileUrls, useInbox, useLinkPreviews, useMessageActions, usePeople, usePerson, usePins, useScheduled, useSearch, useStartConversation, useTopics, useUnreadTotal } from './chunk-JU2FAPBI.js';
1
+ export { CATCH_UP_MAX_PAGES, CATCH_UP_PAGE, ChatProvider, LINK_PREVIEW_CONCURRENCY, belongsTo, chatKeys, hostedUploadFrom, useAvailability, useBroadcast, useChat, useConversation, useDebouncedValue, useFileUrls, useInbox, useLinkPreviews, useMessageActions, usePeople, usePerson, usePins, useScheduled, useSearch, useStartConversation, useTopics, useUnreadTotal } from './chunk-XQ2ULNHV.js';
2
2
  import './chunk-A4YJX7KT.js';
3
3
  import './chunk-GBJ3YI4E.js';
4
4
  //# sourceMappingURL=react.js.map
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CHAT_BUCKET, CHAT_SCHEMA } from './chunk-GBJ3YI4E.js';
2
- import { chatPushPayload } from './chunk-VEPZROQB.js';
2
+ import { chatPushPayload } from './chunk-BTG4JWLF.js';
3
3
 
4
4
  // src/server/runner.ts
5
5
  var CHAT_MAX_ATTEMPTS = 8;
package/dist/web.d.ts CHANGED
@@ -82,7 +82,7 @@ interface ChatAttachmentCardProps {
82
82
  action?: {
83
83
  label: string;
84
84
  href?: string;
85
- onPress?: () => void;
85
+ onPress?: () => void | Promise<unknown>;
86
86
  } | null;
87
87
  tone?: "default" | "primary";
88
88
  className?: string;
@@ -584,7 +584,8 @@ declare function ChatSearch({ resolveUser, conversationId, onOpen, conversationT
584
584
  * `ChatErrorBoundary`: what one message (or one app attachment card) draws can't take the whole
585
585
  * thread down. Messages carry what other people sent, and app renderers get sender-controlled
586
586
  * data, so a render that throws shows its fallback instead, and the error goes to `onError`
587
- * (console.error by default) so it is never silent.
587
+ * (console.error by default) so it is never silent. `resetKeys` lets it try again once what it
588
+ * draws changes (the app's data arrived).
588
589
  */
589
590
 
590
591
  interface ChatErrorBoundaryProps {
@@ -592,6 +593,8 @@ interface ChatErrorBoundaryProps {
592
593
  fallback: ReactNode;
593
594
  /** Told about the error; console.error by default. */
594
595
  onError?: (error: unknown, info: ErrorInfo) => void;
596
+ /** When any of these changes (by identity), a boundary showing its fallback tries the children again. */
597
+ resetKeys?: readonly unknown[];
595
598
  children: ReactNode;
596
599
  }
597
600
  declare class ChatErrorBoundary extends Component<ChatErrorBoundaryProps, {
@@ -603,6 +606,7 @@ declare class ChatErrorBoundary extends Component<ChatErrorBoundaryProps, {
603
606
  static getDerivedStateFromError(): {
604
607
  failed: boolean;
605
608
  };
609
+ componentDidUpdate(prev: ChatErrorBoundaryProps): void;
606
610
  componentDidCatch(error: unknown, info: ErrorInfo): void;
607
611
  render(): ReactNode;
608
612
  }
package/dist/web.js CHANGED
@@ -1,9 +1,10 @@
1
- import { attachmentPreview } from './chunk-AZS3HNLM.js';
1
+ import { attachmentPreview, ChatErrorBoundary } from './chunk-IEFULAC2.js';
2
+ export { ChatErrorBoundary } from './chunk-IEFULAC2.js';
2
3
  import { snippetParts, isHttpsUrl, scheduleQuickPicks, isSchedulable, scheduleLabel, extractLinks, topicKey } from './chunk-BJCE5O7V.js';
3
- import { useChat, useInbox, useSearch, useScheduled, useAvailability, useTopics, useConversation, useMessageActions, usePins, useFileUrls, useLinkPreviews, useBroadcast } from './chunk-JU2FAPBI.js';
4
+ import { useChat, useInbox, useSearch, useScheduled, useAvailability, useTopics, useConversation, useMessageActions, usePins, useFileUrls, useLinkPreviews, useBroadcast } from './chunk-XQ2ULNHV.js';
4
5
  import { previewText, summarizeReactions, activityLine, itemSender, startsDay, dayLabel, itemTime, startsGroup, parseMentions } from './chunk-A4YJX7KT.js';
5
6
  import { fileExtension, formatDuration, nextPlaybackRate, awaySummary, awayLine, WEEKDAYS, CHAT_LIMITS, waveformPeaks, recordingLimitMs, isAllowedExtension, attachmentKindFor, randomId, ChatError } from './chunk-GBJ3YI4E.js';
6
- import { createContext, useRef, useState, Fragment, Component, useCallback, useEffect, useMemo, useImperativeHandle, useLayoutEffect, useContext } from 'react';
7
+ import { createContext, useRef, useState, Fragment, useCallback, useEffect, useMemo, useImperativeHandle, useLayoutEffect, useContext } from 'react';
7
8
  import { MessageSquare, Pin, BellOff, AtSign, Search, X, Mic, ClipboardList, ExternalLink, VideoOff, Video, RotateCcw, SendHorizontal, Square, Circle, Pause, Play, Paperclip, ChevronLeft, ChevronRight, FileText, Download, Lock, Ban, EyeOff, ShieldAlert, AlertCircle, Clock, Reply, Copy, Pencil, PinOff, Bookmark, Flag, Trash2, SmilePlus, Plus, MoreHorizontal, ChevronUp, CalendarClock, Moon, RefreshCw, Smile, Hash, LockOpen, ArrowDown, ImagePlus, Megaphone, Link2, ArrowLeft } from 'lucide-react';
8
9
  import { Skeleton, cn, EmptyState, Button, UserAvatar, Badge, Input, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Alert, AlertDescription, Spinner, Collapsible, CollapsibleTrigger, CollapsibleContent, VisuallyHidden, Progress, ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuSeparator, ContextMenuItem, Tooltip, Textarea, Popover, PopoverTrigger, PopoverContent, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuSeparator, DropdownMenuItem, DropdownMenuLabel, Label, DialogFooter, toast, Switch, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Toggle, ToggleGroup, ToggleGroupItem, Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, RadioGroup, RadioGroupItem, Split, Checkbox } from '@marktiderman/genesis-ui';
9
10
  import { renderSlot } from '@marktiderman/genesis-core/slots';
@@ -481,24 +482,11 @@ function ChatAttachmentCard({ title, subtitle, icon: Icon = ClipboardList, actio
481
482
  action && (href || action.onPress) ? href ? /* @__PURE__ */ jsx(Button, { asChild: true, size: "sm", variant: primary ? "secondary" : "default", className: "shrink-0", children: /* @__PURE__ */ jsxs("a", { href, target: /^https?:/i.test(href) ? "_blank" : void 0, rel: "noopener noreferrer", children: [
482
483
  action.label,
483
484
  /^https?:/i.test(href) ? /* @__PURE__ */ jsx(ExternalLink, { "aria-hidden": true }) : null
484
- ] }) }) : /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", variant: primary ? "secondary" : "default", className: "shrink-0", onClick: action.onPress, children: action.label }) : null
485
+ ] }) }) : /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", variant: primary ? "secondary" : "default", className: "shrink-0", onClick: () => void Promise.resolve(action.onPress?.()).catch((e) => console.error("genesis-chat: a card's action failed", e)), children: action.label }) : null
485
486
  ]
486
487
  }
487
488
  );
488
489
  }
489
- var ChatErrorBoundary = class extends Component {
490
- state = { failed: false };
491
- static getDerivedStateFromError() {
492
- return { failed: true };
493
- }
494
- componentDidCatch(error, info) {
495
- if (this.props.onError) this.props.onError(error, info);
496
- else console.error("genesis-chat: a message couldn't be drawn", error);
497
- }
498
- render() {
499
- return this.state.failed ? this.props.fallback : this.props.children;
500
- }
501
- };
502
490
  function pickVideoMimeType() {
503
491
  if (typeof MediaRecorder === "undefined") return null;
504
492
  for (const type of ["video/mp4;codecs=avc1,mp4a", "video/mp4", "video/webm;codecs=vp9,opus", "video/webm;codecs=vp8,opus", "video/webm"]) {
@@ -4120,6 +4108,6 @@ function ChatBroadcast({ resolveUser, kind, filter, onSent, className }) {
4120
4108
  );
4121
4109
  }
4122
4110
 
4123
- export { ChatAttachmentCard, ChatAvailabilitySettings, ChatAwayBanner, ChatBroadcast, ChatComposer, ChatEmojiPicker, ChatErrorBoundary, ChatInbox, ChatLinkPreview, ChatMarkdown, ChatPanel, ChatScheduleMenu, ChatScheduledList, ChatSearch, ChatThread, ChatTopicBar, ChatVideoPlayer, ChatVideoRecorder, FileChip, GenericAttachment, ImageGrid, Lightbox, MessageAttachments, MessageRow, QUICK_REACTIONS, SearchSnippet, VideoAttachment, VoiceNote, canPickEmoji, clockTime, createMemoryChatClient, formatBytes, inboxTitle, isSafeHref, linkPreviewImageSrc, messageLabel, muxPosterUrl, muxStreamUrl, parseMarkdown, pickVideoMimeType, pickVoiceMimeType, plainText, relativeTime, toAttachmentView, toLocalInput, uploadVideo, useVideoRecorder, useVoiceRecorder, videoFile, voiceFile };
4111
+ export { ChatAttachmentCard, ChatAvailabilitySettings, ChatAwayBanner, ChatBroadcast, ChatComposer, ChatEmojiPicker, ChatInbox, ChatLinkPreview, ChatMarkdown, ChatPanel, ChatScheduleMenu, ChatScheduledList, ChatSearch, ChatThread, ChatTopicBar, ChatVideoPlayer, ChatVideoRecorder, FileChip, GenericAttachment, ImageGrid, Lightbox, MessageAttachments, MessageRow, QUICK_REACTIONS, SearchSnippet, VideoAttachment, VoiceNote, canPickEmoji, clockTime, createMemoryChatClient, formatBytes, inboxTitle, isSafeHref, linkPreviewImageSrc, messageLabel, muxPosterUrl, muxStreamUrl, parseMarkdown, pickVideoMimeType, pickVoiceMimeType, plainText, relativeTime, toAttachmentView, toLocalInput, uploadVideo, useVideoRecorder, useVoiceRecorder, videoFile, voiceFile };
4124
4112
  //# sourceMappingURL=web.js.map
4125
4113
  //# sourceMappingURL=web.js.map