@planningcenter/chat-react-native 4.4.1-qa-staging.8 → 4.4.1-qa-staging.10

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 (55) hide show
  1. package/build/components/conversation/system_message.d.ts.map +1 -1
  2. package/build/components/conversation/system_message.js +85 -74
  3. package/build/components/conversation/system_message.js.map +1 -1
  4. package/build/components/conversations/conversation_preview.js +2 -0
  5. package/build/components/conversations/conversation_preview.js.map +1 -1
  6. package/build/hooks/use_features.d.ts +2 -0
  7. package/build/hooks/use_features.d.ts.map +1 -1
  8. package/build/hooks/use_features.js +2 -0
  9. package/build/hooks/use_features.js.map +1 -1
  10. package/build/hooks/use_filter_dropdown_enabled.d.ts +2 -0
  11. package/build/hooks/use_filter_dropdown_enabled.d.ts.map +1 -0
  12. package/build/hooks/use_filter_dropdown_enabled.js +18 -0
  13. package/build/hooks/use_filter_dropdown_enabled.js.map +1 -0
  14. package/build/types/jolt_events/message_events.d.ts +2 -0
  15. package/build/types/jolt_events/message_events.d.ts.map +1 -1
  16. package/build/types/jolt_events/message_events.js.map +1 -1
  17. package/build/types/resources/conversation.d.ts +1 -1
  18. package/build/types/resources/conversation.d.ts.map +1 -1
  19. package/build/types/resources/conversation.js.map +1 -1
  20. package/build/types/resources/message.d.ts +2 -0
  21. package/build/types/resources/message.d.ts.map +1 -1
  22. package/build/types/resources/message.js.map +1 -1
  23. package/build/utils/date.d.ts +1 -0
  24. package/build/utils/date.d.ts.map +1 -1
  25. package/build/utils/date.js +15 -1
  26. package/build/utils/date.js.map +1 -1
  27. package/build/utils/jolt/transform_message_event_data_to_message_resource.d.ts.map +1 -1
  28. package/build/utils/jolt/transform_message_event_data_to_message_resource.js +2 -1
  29. package/build/utils/jolt/transform_message_event_data_to_message_resource.js.map +1 -1
  30. package/build/utils/request/messages_data_options.d.ts.map +1 -1
  31. package/build/utils/request/messages_data_options.js +1 -1
  32. package/build/utils/request/messages_data_options.js.map +1 -1
  33. package/build/utils/system_messages.d.ts +7 -5
  34. package/build/utils/system_messages.d.ts.map +1 -1
  35. package/build/utils/system_messages.js +10 -2
  36. package/build/utils/system_messages.js.map +1 -1
  37. package/package.json +3 -3
  38. package/src/__tests__/hooks/use_filter_dropdown_enabled.test.tsx +42 -0
  39. package/src/__tests__/utils/system_messages.ts +19 -32
  40. package/src/components/conversation/__tests__/system_message.test.tsx +104 -0
  41. package/src/components/conversation/system_message.tsx +20 -6
  42. package/src/components/conversations/__tests__/conversation_preview.test.tsx +70 -0
  43. package/src/components/conversations/conversation_preview.tsx +4 -0
  44. package/src/hooks/use_features.ts +2 -0
  45. package/src/hooks/use_filter_dropdown_enabled.ts +10 -0
  46. package/src/types/jolt_events/message_events.ts +2 -0
  47. package/src/types/resources/conversation.ts +1 -1
  48. package/src/types/resources/message.ts +3 -0
  49. package/src/utils/__tests__/date.test.ts +19 -0
  50. package/src/utils/__tests__/group_messages.test.ts +1 -0
  51. package/src/utils/date.ts +8 -1
  52. package/src/utils/jolt/__tests__/transform_message_event_data_to_message_resource.test.ts +35 -0
  53. package/src/utils/jolt/transform_message_event_data_to_message_resource.ts +1 -0
  54. package/src/utils/request/messages_data_options.ts +1 -0
  55. package/src/utils/system_messages.ts +19 -10
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../src/types/resources/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAElD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,UAAU,GAAG,SAAS,CAAA;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;IAC5C,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,cAAc,CAAA;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,yBAAyB,EAAE,CAAA;IACpC,iBAAiB,CAAC,EAAE,yBAAyB,CAAA;IAC7C,sBAAsB,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,CAAA;IAChE,mBAAmB,EAAE,uBAAuB,GAAG,IAAI,CAAA;IACnD,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,MAAM,CAAC,EAAE,aAAa,EAAE,CAAA;IACxB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;IACpD,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,aAAa,CAAC,EAAE,qBAAqB,CAAA;IACrC,KAAK,EAAE,OAAO,CAAA;IACd,eAAe,EAAE,OAAO,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,oBAAoB,EAClB,kBAAkB,GAClB,iBAAiB,GACjB,mBAAmB,GACnB,sBAAsB,GACtB,mBAAmB,CACtB,CAAA"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../src/types/resources/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAElD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAA;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;IAC5C,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,cAAc,CAAA;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,yBAAyB,EAAE,CAAA;IACpC,iBAAiB,CAAC,EAAE,yBAAyB,CAAA;IAC7C,sBAAsB,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,CAAA;IAChE,mBAAmB,EAAE,uBAAuB,GAAG,IAAI,CAAA;IACnD,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,MAAM,CAAC,EAAE,aAAa,EAAE,CAAA;IACxB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;IACpD,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,aAAa,CAAC,EAAE,qBAAqB,CAAA;IACrC,KAAK,EAAE,OAAO,CAAA;IACd,eAAe,EAAE,OAAO,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,oBAAoB,EAClB,kBAAkB,GAClB,iBAAiB,GACjB,mBAAmB,GACnB,sBAAsB,GACtB,mBAAmB,CACtB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.js","names":[],"sources":["../../../src/types/resources/conversation.ts"],"sourcesContent":["import type { AnalyticsMetadataResource } from './analytics_metadata'\nimport { ConversationBadgeResource } from './conversation_badge'\nimport { ConversationMembershipResource } from './conversation_membership'\nimport { GroupResource } from './group_resource'\nimport { MemberAbilityResource } from './member_ability'\nimport { ReactionCountResource } from './reaction'\n\nexport interface ConversationPreviewData {\n kind: 'reaction' | 'message'\n authorName: string\n value: ReactionCountResource['value'] | null\n text: string\n createdAt: string\n}\n\nexport interface ConversationResource {\n type: 'Conversation'\n id: number\n badges?: ConversationBadgeResource[]\n analyticsMetadata?: AnalyticsMetadataResource\n conversationMembership?: Partial<ConversationMembershipResource>\n conversationPreview: ConversationPreviewData | null\n createdAt: string\n deleted?: boolean\n directMessage?: boolean\n disabled?: boolean\n disabledReason?: string | null\n disabledMessage?: string | null\n genderOption?: string | null\n groups?: GroupResource[]\n previewAvatarUrls?: string[]\n customAvatarType?: 'image' | 'icon' | 'emoji' | null\n customAvatarKey?: string | null\n customAvatarColor?: string | null\n customAvatarImageUrl?: string | null\n lastMessageAuthorId?: string\n lastMessageAuthorName?: string\n lastMessageCreatedAt?: string\n lastMessageTextPreview?: string\n latestReadMessageSortKey?: string\n memberAbility?: MemberAbilityResource\n muted: boolean\n repliesDisabled: boolean\n title: string\n unreadCount: number\n unreadReaction: boolean\n updatedAt: string\n}\n\nexport type ConversationAvatarData = Pick<\n ConversationResource,\n | 'customAvatarType'\n | 'customAvatarKey'\n | 'customAvatarColor'\n | 'customAvatarImageUrl'\n | 'previewAvatarUrls'\n>\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"conversation.js","names":[],"sources":["../../../src/types/resources/conversation.ts"],"sourcesContent":["import type { AnalyticsMetadataResource } from './analytics_metadata'\nimport { ConversationBadgeResource } from './conversation_badge'\nimport { ConversationMembershipResource } from './conversation_membership'\nimport { GroupResource } from './group_resource'\nimport { MemberAbilityResource } from './member_ability'\nimport { ReactionCountResource } from './reaction'\n\nexport interface ConversationPreviewData {\n kind: 'reaction' | 'message' | 'system'\n authorName: string\n value: ReactionCountResource['value'] | null\n text: string\n createdAt: string\n}\n\nexport interface ConversationResource {\n type: 'Conversation'\n id: number\n badges?: ConversationBadgeResource[]\n analyticsMetadata?: AnalyticsMetadataResource\n conversationMembership?: Partial<ConversationMembershipResource>\n conversationPreview: ConversationPreviewData | null\n createdAt: string\n deleted?: boolean\n directMessage?: boolean\n disabled?: boolean\n disabledReason?: string | null\n disabledMessage?: string | null\n genderOption?: string | null\n groups?: GroupResource[]\n previewAvatarUrls?: string[]\n customAvatarType?: 'image' | 'icon' | 'emoji' | null\n customAvatarKey?: string | null\n customAvatarColor?: string | null\n customAvatarImageUrl?: string | null\n lastMessageAuthorId?: string\n lastMessageAuthorName?: string\n lastMessageCreatedAt?: string\n lastMessageTextPreview?: string\n latestReadMessageSortKey?: string\n memberAbility?: MemberAbilityResource\n muted: boolean\n repliesDisabled: boolean\n title: string\n unreadCount: number\n unreadReaction: boolean\n updatedAt: string\n}\n\nexport type ConversationAvatarData = Pick<\n ConversationResource,\n | 'customAvatarType'\n | 'customAvatarKey'\n | 'customAvatarColor'\n | 'customAvatarImageUrl'\n | 'previewAvatarUrls'\n>\n"],"mappings":"","ignoreList":[]}
@@ -2,6 +2,7 @@ import { DenormalizedAttachmentResource } from './denormalized_attachment_resour
2
2
  import { DenormalizedAttachmentResourceForCreate } from './denormalized_attachment_resource_for_create';
3
3
  import type { PersonResource } from './person';
4
4
  import type { ReactionCountResource } from './reaction';
5
+ export type SystemTextFormat = 'people' | 'actor';
5
6
  export interface MessageResource {
6
7
  type: 'Message';
7
8
  id: string;
@@ -25,6 +26,7 @@ export interface MessageResource {
25
26
  overflowCount: number;
26
27
  action: string;
27
28
  } | null;
29
+ systemTextFormat?: SystemTextFormat | null;
28
30
  renderAuthor?: boolean;
29
31
  renderTime?: boolean;
30
32
  myLatestInConversation?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/types/resources/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAA;AACnF,OAAO,EAAE,uCAAuC,EAAE,MAAM,+CAA+C,CAAA;AACvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,8BAA8B,EAAE,CAAA;IAC7C,MAAM,EAAE,cAAc,CAAA;IACtB,cAAc,EAAE,qBAAqB,EAAE,CAAA;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IAClC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,uBAAuB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IACzC,eAAe,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAGnF,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAA;IACnD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,wBAAwB,CAAC,EAAE,OAAO,CAAA;IAGlC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oBAAoB,CAAC,EAAE,uCAAuC,EAAE,CAAA;CACjE"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/types/resources/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAA;AACnF,OAAO,EAAE,uCAAuC,EAAE,MAAM,+CAA+C,CAAA;AACvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,OAAO,CAAA;AAEjD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,8BAA8B,EAAE,CAAA;IAC7C,MAAM,EAAE,cAAc,CAAA;IACtB,cAAc,EAAE,qBAAqB,EAAE,CAAA;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IAClC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,uBAAuB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IACzC,eAAe,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IACnF,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAG1C,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAA;IACnD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,wBAAwB,CAAC,EAAE,OAAO,CAAA;IAGlC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oBAAoB,CAAC,EAAE,uCAAuC,EAAE,CAAA;CACjE"}
@@ -1 +1 @@
1
- {"version":3,"file":"message.js","names":[],"sources":["../../../src/types/resources/message.ts"],"sourcesContent":["import { DenormalizedAttachmentResource } from './denormalized_attachment_resource'\nimport { DenormalizedAttachmentResourceForCreate } from './denormalized_attachment_resource_for_create'\nimport type { PersonResource } from './person'\nimport type { ReactionCountResource } from './reaction'\n\nexport interface MessageResource {\n type: 'Message'\n id: string\n text: string | null\n html: string\n createdAt: string\n deletedAt: string | null\n textEditedAt: string | null\n mine: boolean\n attachments: DenormalizedAttachmentResource[]\n author: PersonResource\n reactionCounts: ReactionCountResource[]\n replyCount: number\n replyRootId?: string | null\n replyRoot?: MessageResource | null\n idempotentKey?: string | null\n messageType: string\n personIdsForSystemEvent?: number[] | null\n systemTextParts?: { names: string[]; overflowCount: number; action: string } | null\n\n // Custom Local Properties we set for rendering\n renderAuthor?: boolean\n renderTime?: boolean\n myLatestInConversation?: boolean\n lastInGroup?: boolean\n threadPosition?: 'first' | 'center' | 'last' | null\n prevIsMyReply?: boolean\n nextIsMyReply?: boolean\n nextRendersAuthor?: boolean\n isReplyShadowMessage?: boolean\n nextIsReplyShadowMessage?: boolean\n\n // Properties for mutation state\n pending?: boolean // Indicates if the message is optimistically created and pending server response\n error?: string // Error message if the message failed to send\n attachmentsForCreate?: DenormalizedAttachmentResourceForCreate[]\n}\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"message.js","names":[],"sources":["../../../src/types/resources/message.ts"],"sourcesContent":["import { DenormalizedAttachmentResource } from './denormalized_attachment_resource'\nimport { DenormalizedAttachmentResourceForCreate } from './denormalized_attachment_resource_for_create'\nimport type { PersonResource } from './person'\nimport type { ReactionCountResource } from './reaction'\n\nexport type SystemTextFormat = 'people' | 'actor'\n\nexport interface MessageResource {\n type: 'Message'\n id: string\n text: string | null\n html: string\n createdAt: string\n deletedAt: string | null\n textEditedAt: string | null\n mine: boolean\n attachments: DenormalizedAttachmentResource[]\n author: PersonResource\n reactionCounts: ReactionCountResource[]\n replyCount: number\n replyRootId?: string | null\n replyRoot?: MessageResource | null\n idempotentKey?: string | null\n messageType: string\n personIdsForSystemEvent?: number[] | null\n systemTextParts?: { names: string[]; overflowCount: number; action: string } | null\n systemTextFormat?: SystemTextFormat | null\n\n // Custom Local Properties we set for rendering\n renderAuthor?: boolean\n renderTime?: boolean\n myLatestInConversation?: boolean\n lastInGroup?: boolean\n threadPosition?: 'first' | 'center' | 'last' | null\n prevIsMyReply?: boolean\n nextIsMyReply?: boolean\n nextRendersAuthor?: boolean\n isReplyShadowMessage?: boolean\n nextIsReplyShadowMessage?: boolean\n\n // Properties for mutation state\n pending?: boolean // Indicates if the message is optimistically created and pending server response\n error?: string // Error message if the message failed to send\n attachmentsForCreate?: DenormalizedAttachmentResourceForCreate[]\n}\n"],"mappings":"","ignoreList":[]}
@@ -7,4 +7,5 @@ export declare function getRelativeDateStatus(date: DateProps): {
7
7
  };
8
8
  export declare function relativeDateTime(dateTimeString: string): string;
9
9
  export declare function relativeTime(date: DateProps): string;
10
+ export declare function formatEventDateTime(date: DateProps): string;
10
11
  //# sourceMappingURL=date.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/utils/date.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAE9C,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,SAAS,UAcjD;AAOD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS;;;;EAQpD;AAED,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAc/D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAUpD"}
1
+ {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/utils/date.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAE9C,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,SAAS,UAcjD;AAOD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS;;;;EAQpD;AAED,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAc/D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAUpD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,UAKlD"}
@@ -1,4 +1,4 @@
1
- import { date as formatDate } from '@planningcenter/datetime-fmt';
1
+ import { date as formatDate, time as formatTime } from '@planningcenter/datetime-fmt';
2
2
  import dayjs from './dayjs';
3
3
  export function formatDatePreview(date) {
4
4
  if (!date) return '';
@@ -65,4 +65,18 @@ export function relativeTime(date) {
65
65
  return dayjs(date).format('h:mma');
66
66
  }
67
67
  }
68
+ export function formatEventDateTime(date) {
69
+ const {
70
+ isThisYear
71
+ } = getRelativeDateStatus(date);
72
+ const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
73
+ const day = formatDate(date, {
74
+ style: 'abbreviated',
75
+ year: !isThisYear,
76
+ timeZone
77
+ });
78
+ return `${day} at ${formatTime(date, {
79
+ timeZone
80
+ })}`;
81
+ }
68
82
  //# sourceMappingURL=date.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"date.js","names":["date","formatDate","dayjs","formatDatePreview","now","isToday","isSame","isThisWeek","isThisYear","format","style","formatShorterDate","year","replace","getRelativeDateStatus","relativeDateTime","dateTimeString","Date","toDateString","getFullYear","toLocaleTimeString","hour","minute","hour12","toLocaleDateString","month","day","relativeTime","then","duration","diff","asDays","fromNow"],"sources":["../../src/utils/date.ts"],"sourcesContent":["import { date as formatDate } from '@planningcenter/datetime-fmt'\nimport dayjs from './dayjs'\n\nexport type DateProps = string | number | Date\n\nexport function formatDatePreview(date?: DateProps) {\n if (!date) return ''\n\n const now = dayjs()\n const isToday = now.isSame(date, 'day')\n const isThisWeek = now.isSame(date, 'week')\n const isThisYear = now.isSame(date, 'year')\n\n if (isToday) return dayjs(date).format('h:mma')\n if (isThisWeek) return formatDate(date, { style: 'relative-short' })\n if (isThisYear) return formatDate(date, { style: 'abbreviated' })\n\n // TODO: Org date format\n return formatShorterDate(date)\n}\n\nconst formatShorterDate = (date: DateProps) => {\n // Drop the century from the year\n return formatDate(date, { style: 'short', year: true }).replace(/20(\\d{2})/, '$1')\n}\n\nexport function getRelativeDateStatus(date: DateProps) {\n const now = dayjs()\n\n const isToday = now.isSame(date, 'day')\n const isThisWeek = now.isSame(date, 'week')\n const isThisYear = now.isSame(date, 'year')\n\n return { isToday, isThisWeek, isThisYear }\n}\n\nexport function relativeDateTime(dateTimeString: string): string {\n const date = new Date(dateTimeString)\n const now = new Date()\n\n const isToday = date.toDateString() === now.toDateString()\n const isThisYear = date.getFullYear() === now.getFullYear()\n\n if (isToday) {\n return date.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true })\n } else if (isThisYear) {\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })\n } else {\n return date.toLocaleDateString('en-US')\n }\n}\n\nexport function relativeTime(date: DateProps): string {\n const now = dayjs()\n const then = dayjs(date)\n const duration = dayjs.duration(now.diff(then))\n\n if (duration.asDays() < 1) {\n return then.fromNow()\n } else {\n return dayjs(date).format('h:mma')\n }\n}\n"],"mappings":"AAAA,SAASA,IAAI,IAAIC,UAAU,QAAQ,8BAA8B;AACjE,OAAOC,KAAK,MAAM,SAAS;AAI3B,OAAO,SAASC,iBAAiBA,CAACH,IAAgB,EAAE;EAClD,IAAI,CAACA,IAAI,EAAE,OAAO,EAAE;EAEpB,MAAMI,GAAG,GAAGF,KAAK,CAAC,CAAC;EACnB,MAAMG,OAAO,GAAGD,GAAG,CAACE,MAAM,CAACN,IAAI,EAAE,KAAK,CAAC;EACvC,MAAMO,UAAU,GAAGH,GAAG,CAACE,MAAM,CAACN,IAAI,EAAE,MAAM,CAAC;EAC3C,MAAMQ,UAAU,GAAGJ,GAAG,CAACE,MAAM,CAACN,IAAI,EAAE,MAAM,CAAC;EAE3C,IAAIK,OAAO,EAAE,OAAOH,KAAK,CAACF,IAAI,CAAC,CAACS,MAAM,CAAC,OAAO,CAAC;EAC/C,IAAIF,UAAU,EAAE,OAAON,UAAU,CAACD,IAAI,EAAE;IAAEU,KAAK,EAAE;EAAiB,CAAC,CAAC;EACpE,IAAIF,UAAU,EAAE,OAAOP,UAAU,CAACD,IAAI,EAAE;IAAEU,KAAK,EAAE;EAAc,CAAC,CAAC;;EAEjE;EACA,OAAOC,iBAAiB,CAACX,IAAI,CAAC;AAChC;AAEA,MAAMW,iBAAiB,GAAIX,IAAe,IAAK;EAC7C;EACA,OAAOC,UAAU,CAACD,IAAI,EAAE;IAAEU,KAAK,EAAE,OAAO;IAAEE,IAAI,EAAE;EAAK,CAAC,CAAC,CAACC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC;AACpF,CAAC;AAED,OAAO,SAASC,qBAAqBA,CAACd,IAAe,EAAE;EACrD,MAAMI,GAAG,GAAGF,KAAK,CAAC,CAAC;EAEnB,MAAMG,OAAO,GAAGD,GAAG,CAACE,MAAM,CAACN,IAAI,EAAE,KAAK,CAAC;EACvC,MAAMO,UAAU,GAAGH,GAAG,CAACE,MAAM,CAACN,IAAI,EAAE,MAAM,CAAC;EAC3C,MAAMQ,UAAU,GAAGJ,GAAG,CAACE,MAAM,CAACN,IAAI,EAAE,MAAM,CAAC;EAE3C,OAAO;IAAEK,OAAO;IAAEE,UAAU;IAAEC;EAAW,CAAC;AAC5C;AAEA,OAAO,SAASO,gBAAgBA,CAACC,cAAsB,EAAU;EAC/D,MAAMhB,IAAI,GAAG,IAAIiB,IAAI,CAACD,cAAc,CAAC;EACrC,MAAMZ,GAAG,GAAG,IAAIa,IAAI,CAAC,CAAC;EAEtB,MAAMZ,OAAO,GAAGL,IAAI,CAACkB,YAAY,CAAC,CAAC,KAAKd,GAAG,CAACc,YAAY,CAAC,CAAC;EAC1D,MAAMV,UAAU,GAAGR,IAAI,CAACmB,WAAW,CAAC,CAAC,KAAKf,GAAG,CAACe,WAAW,CAAC,CAAC;EAE3D,IAAId,OAAO,EAAE;IACX,OAAOL,IAAI,CAACoB,kBAAkB,CAAC,OAAO,EAAE;MAAEC,IAAI,EAAE,SAAS;MAAEC,MAAM,EAAE,SAAS;MAAEC,MAAM,EAAE;IAAK,CAAC,CAAC;EAC/F,CAAC,MAAM,IAAIf,UAAU,EAAE;IACrB,OAAOR,IAAI,CAACwB,kBAAkB,CAAC,OAAO,EAAE;MAAEC,KAAK,EAAE,OAAO;MAAEC,GAAG,EAAE;IAAU,CAAC,CAAC;EAC7E,CAAC,MAAM;IACL,OAAO1B,IAAI,CAACwB,kBAAkB,CAAC,OAAO,CAAC;EACzC;AACF;AAEA,OAAO,SAASG,YAAYA,CAAC3B,IAAe,EAAU;EACpD,MAAMI,GAAG,GAAGF,KAAK,CAAC,CAAC;EACnB,MAAM0B,IAAI,GAAG1B,KAAK,CAACF,IAAI,CAAC;EACxB,MAAM6B,QAAQ,GAAG3B,KAAK,CAAC2B,QAAQ,CAACzB,GAAG,CAAC0B,IAAI,CAACF,IAAI,CAAC,CAAC;EAE/C,IAAIC,QAAQ,CAACE,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE;IACzB,OAAOH,IAAI,CAACI,OAAO,CAAC,CAAC;EACvB,CAAC,MAAM;IACL,OAAO9B,KAAK,CAACF,IAAI,CAAC,CAACS,MAAM,CAAC,OAAO,CAAC;EACpC;AACF","ignoreList":[]}
1
+ {"version":3,"file":"date.js","names":["date","formatDate","time","formatTime","dayjs","formatDatePreview","now","isToday","isSame","isThisWeek","isThisYear","format","style","formatShorterDate","year","replace","getRelativeDateStatus","relativeDateTime","dateTimeString","Date","toDateString","getFullYear","toLocaleTimeString","hour","minute","hour12","toLocaleDateString","month","day","relativeTime","then","duration","diff","asDays","fromNow","formatEventDateTime","timeZone","Intl","DateTimeFormat","resolvedOptions"],"sources":["../../src/utils/date.ts"],"sourcesContent":["import { date as formatDate, time as formatTime } from '@planningcenter/datetime-fmt'\nimport dayjs from './dayjs'\n\nexport type DateProps = string | number | Date\n\nexport function formatDatePreview(date?: DateProps) {\n if (!date) return ''\n\n const now = dayjs()\n const isToday = now.isSame(date, 'day')\n const isThisWeek = now.isSame(date, 'week')\n const isThisYear = now.isSame(date, 'year')\n\n if (isToday) return dayjs(date).format('h:mma')\n if (isThisWeek) return formatDate(date, { style: 'relative-short' })\n if (isThisYear) return formatDate(date, { style: 'abbreviated' })\n\n // TODO: Org date format\n return formatShorterDate(date)\n}\n\nconst formatShorterDate = (date: DateProps) => {\n // Drop the century from the year\n return formatDate(date, { style: 'short', year: true }).replace(/20(\\d{2})/, '$1')\n}\n\nexport function getRelativeDateStatus(date: DateProps) {\n const now = dayjs()\n\n const isToday = now.isSame(date, 'day')\n const isThisWeek = now.isSame(date, 'week')\n const isThisYear = now.isSame(date, 'year')\n\n return { isToday, isThisWeek, isThisYear }\n}\n\nexport function relativeDateTime(dateTimeString: string): string {\n const date = new Date(dateTimeString)\n const now = new Date()\n\n const isToday = date.toDateString() === now.toDateString()\n const isThisYear = date.getFullYear() === now.getFullYear()\n\n if (isToday) {\n return date.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true })\n } else if (isThisYear) {\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })\n } else {\n return date.toLocaleDateString('en-US')\n }\n}\n\nexport function relativeTime(date: DateProps): string {\n const now = dayjs()\n const then = dayjs(date)\n const duration = dayjs.duration(now.diff(then))\n\n if (duration.asDays() < 1) {\n return then.fromNow()\n } else {\n return dayjs(date).format('h:mma')\n }\n}\n\nexport function formatEventDateTime(date: DateProps) {\n const { isThisYear } = getRelativeDateStatus(date)\n const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone\n const day = formatDate(date, { style: 'abbreviated', year: !isThisYear, timeZone })\n return `${day} at ${formatTime(date, { timeZone })}`\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"transform_message_event_data_to_message_resource.d.ts","sourceRoot":"","sources":["../../../src/utils/jolt/transform_message_event_data_to_message_resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA;AAI5E,wBAAgB,0CAA0C,CAAC,EACzD,IAAI,EACJ,eAAe,GAChB,EAAE;IACD,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;IACzC,eAAe,EAAE,MAAM,CAAA;CACxB,GAAG,eAAe,CA+BlB"}
1
+ {"version":3,"file":"transform_message_event_data_to_message_resource.d.ts","sourceRoot":"","sources":["../../../src/utils/jolt/transform_message_event_data_to_message_resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA;AAI5E,wBAAgB,0CAA0C,CAAC,EACzD,IAAI,EACJ,eAAe,GAChB,EAAE;IACD,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;IACzC,eAAe,EAAE,MAAM,CAAA;CACxB,GAAG,eAAe,CAgClB"}
@@ -29,7 +29,8 @@ export function transformMessageEventDataToMessageResource({
29
29
  names: data.system_text_parts.names,
30
30
  overflowCount: data.system_text_parts.overflow_count,
31
31
  action: data.system_text_parts.action
32
- } : null
32
+ } : null,
33
+ systemTextFormat: data.system_text_format
33
34
  };
34
35
  }
35
36
  //# sourceMappingURL=transform_message_event_data_to_message_resource.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transform_message_event_data_to_message_resource.js","names":["deepCamelCaseKeys","transformMessageEventDataToMessageResource","data","currentPersonId","type","id","sort_key","text","html","createdAt","created_at","deletedAt","deleted_at","textEditedAt","text_edited_at","mine","author_id","attachments","author","name","author_name","avatar","author_avatar","reactionCounts","replyCount","reply_count","replyRootId","reply_root_id","idempotentKey","idempotent_key","messageType","message_type","personIdsForSystemEvent","system_event_person_ids","systemTextParts","system_text_parts","names","overflowCount","overflow_count","action"],"sources":["../../../src/utils/jolt/transform_message_event_data_to_message_resource.ts"],"sourcesContent":["import { MessageResource } from '../../types'\nimport { MessageCreatedEvent } from '../../types/jolt_events/message_events'\nimport { DenormalizedAttachmentResource } from '../../types/resources/denormalized_attachment_resource'\nimport { deepCamelCaseKeys } from '../deepCamelCaseKeys'\n\nexport function transformMessageEventDataToMessageResource({\n data,\n currentPersonId,\n}: {\n data: MessageCreatedEvent['data']['data']\n currentPersonId: number\n}): MessageResource {\n return {\n type: 'Message',\n id: data.sort_key,\n text: data.text,\n html: data.html,\n createdAt: data.created_at,\n deletedAt: data.deleted_at,\n textEditedAt: data.text_edited_at,\n mine: data.author_id === currentPersonId,\n attachments: deepCamelCaseKeys<DenormalizedAttachmentResource[]>(data.attachments) || [],\n author: {\n type: 'Person',\n id: data.author_id,\n name: data.author_name,\n avatar: data.author_avatar,\n },\n reactionCounts: [],\n replyCount: data.reply_count || 0,\n replyRootId: data.reply_root_id || null,\n idempotentKey: data.idempotent_key ?? null,\n messageType: data.message_type,\n personIdsForSystemEvent: data.system_event_person_ids,\n systemTextParts: data.system_text_parts\n ? {\n names: data.system_text_parts.names,\n overflowCount: data.system_text_parts.overflow_count,\n action: data.system_text_parts.action,\n }\n : null,\n }\n}\n"],"mappings":"AAGA,SAASA,iBAAiB,QAAQ,sBAAsB;AAExD,OAAO,SAASC,0CAA0CA,CAAC;EACzDC,IAAI;EACJC;AAIF,CAAC,EAAmB;EAClB,OAAO;IACLC,IAAI,EAAE,SAAS;IACfC,EAAE,EAAEH,IAAI,CAACI,QAAQ;IACjBC,IAAI,EAAEL,IAAI,CAACK,IAAI;IACfC,IAAI,EAAEN,IAAI,CAACM,IAAI;IACfC,SAAS,EAAEP,IAAI,CAACQ,UAAU;IAC1BC,SAAS,EAAET,IAAI,CAACU,UAAU;IAC1BC,YAAY,EAAEX,IAAI,CAACY,cAAc;IACjCC,IAAI,EAAEb,IAAI,CAACc,SAAS,KAAKb,eAAe;IACxCc,WAAW,EAAEjB,iBAAiB,CAAmCE,IAAI,CAACe,WAAW,CAAC,IAAI,EAAE;IACxFC,MAAM,EAAE;MACNd,IAAI,EAAE,QAAQ;MACdC,EAAE,EAAEH,IAAI,CAACc,SAAS;MAClBG,IAAI,EAAEjB,IAAI,CAACkB,WAAW;MACtBC,MAAM,EAAEnB,IAAI,CAACoB;IACf,CAAC;IACDC,cAAc,EAAE,EAAE;IAClBC,UAAU,EAAEtB,IAAI,CAACuB,WAAW,IAAI,CAAC;IACjCC,WAAW,EAAExB,IAAI,CAACyB,aAAa,IAAI,IAAI;IACvCC,aAAa,EAAE1B,IAAI,CAAC2B,cAAc,IAAI,IAAI;IAC1CC,WAAW,EAAE5B,IAAI,CAAC6B,YAAY;IAC9BC,uBAAuB,EAAE9B,IAAI,CAAC+B,uBAAuB;IACrDC,eAAe,EAAEhC,IAAI,CAACiC,iBAAiB,GACnC;MACEC,KAAK,EAAElC,IAAI,CAACiC,iBAAiB,CAACC,KAAK;MACnCC,aAAa,EAAEnC,IAAI,CAACiC,iBAAiB,CAACG,cAAc;MACpDC,MAAM,EAAErC,IAAI,CAACiC,iBAAiB,CAACI;IACjC,CAAC,GACD;EACN,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"file":"transform_message_event_data_to_message_resource.js","names":["deepCamelCaseKeys","transformMessageEventDataToMessageResource","data","currentPersonId","type","id","sort_key","text","html","createdAt","created_at","deletedAt","deleted_at","textEditedAt","text_edited_at","mine","author_id","attachments","author","name","author_name","avatar","author_avatar","reactionCounts","replyCount","reply_count","replyRootId","reply_root_id","idempotentKey","idempotent_key","messageType","message_type","personIdsForSystemEvent","system_event_person_ids","systemTextParts","system_text_parts","names","overflowCount","overflow_count","action","systemTextFormat","system_text_format"],"sources":["../../../src/utils/jolt/transform_message_event_data_to_message_resource.ts"],"sourcesContent":["import { MessageResource } from '../../types'\nimport { MessageCreatedEvent } from '../../types/jolt_events/message_events'\nimport { DenormalizedAttachmentResource } from '../../types/resources/denormalized_attachment_resource'\nimport { deepCamelCaseKeys } from '../deepCamelCaseKeys'\n\nexport function transformMessageEventDataToMessageResource({\n data,\n currentPersonId,\n}: {\n data: MessageCreatedEvent['data']['data']\n currentPersonId: number\n}): MessageResource {\n return {\n type: 'Message',\n id: data.sort_key,\n text: data.text,\n html: data.html,\n createdAt: data.created_at,\n deletedAt: data.deleted_at,\n textEditedAt: data.text_edited_at,\n mine: data.author_id === currentPersonId,\n attachments: deepCamelCaseKeys<DenormalizedAttachmentResource[]>(data.attachments) || [],\n author: {\n type: 'Person',\n id: data.author_id,\n name: data.author_name,\n avatar: data.author_avatar,\n },\n reactionCounts: [],\n replyCount: data.reply_count || 0,\n replyRootId: data.reply_root_id || null,\n idempotentKey: data.idempotent_key ?? null,\n messageType: data.message_type,\n personIdsForSystemEvent: data.system_event_person_ids,\n systemTextParts: data.system_text_parts\n ? {\n names: data.system_text_parts.names,\n overflowCount: data.system_text_parts.overflow_count,\n action: data.system_text_parts.action,\n }\n : null,\n systemTextFormat: data.system_text_format,\n }\n}\n"],"mappings":"AAGA,SAASA,iBAAiB,QAAQ,sBAAsB;AAExD,OAAO,SAASC,0CAA0CA,CAAC;EACzDC,IAAI;EACJC;AAIF,CAAC,EAAmB;EAClB,OAAO;IACLC,IAAI,EAAE,SAAS;IACfC,EAAE,EAAEH,IAAI,CAACI,QAAQ;IACjBC,IAAI,EAAEL,IAAI,CAACK,IAAI;IACfC,IAAI,EAAEN,IAAI,CAACM,IAAI;IACfC,SAAS,EAAEP,IAAI,CAACQ,UAAU;IAC1BC,SAAS,EAAET,IAAI,CAACU,UAAU;IAC1BC,YAAY,EAAEX,IAAI,CAACY,cAAc;IACjCC,IAAI,EAAEb,IAAI,CAACc,SAAS,KAAKb,eAAe;IACxCc,WAAW,EAAEjB,iBAAiB,CAAmCE,IAAI,CAACe,WAAW,CAAC,IAAI,EAAE;IACxFC,MAAM,EAAE;MACNd,IAAI,EAAE,QAAQ;MACdC,EAAE,EAAEH,IAAI,CAACc,SAAS;MAClBG,IAAI,EAAEjB,IAAI,CAACkB,WAAW;MACtBC,MAAM,EAAEnB,IAAI,CAACoB;IACf,CAAC;IACDC,cAAc,EAAE,EAAE;IAClBC,UAAU,EAAEtB,IAAI,CAACuB,WAAW,IAAI,CAAC;IACjCC,WAAW,EAAExB,IAAI,CAACyB,aAAa,IAAI,IAAI;IACvCC,aAAa,EAAE1B,IAAI,CAAC2B,cAAc,IAAI,IAAI;IAC1CC,WAAW,EAAE5B,IAAI,CAAC6B,YAAY;IAC9BC,uBAAuB,EAAE9B,IAAI,CAAC+B,uBAAuB;IACrDC,eAAe,EAAEhC,IAAI,CAACiC,iBAAiB,GACnC;MACEC,KAAK,EAAElC,IAAI,CAACiC,iBAAiB,CAACC,KAAK;MACnCC,aAAa,EAAEnC,IAAI,CAACiC,iBAAiB,CAACG,cAAc;MACpDC,MAAM,EAAErC,IAAI,CAACiC,iBAAiB,CAACI;IACjC,CAAC,GACD,IAAI;IACRC,gBAAgB,EAAEtC,IAAI,CAACuC;EACzB,CAAC;AACH","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"messages_data_options.d.ts","sourceRoot":"","sources":["../../../src/utils/request/messages_data_options.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;;;CAmB5B,CAAA;AAED,eAAO,MAAM,kBAAkB,UAAmE,CAAA"}
1
+ {"version":3,"file":"messages_data_options.d.ts","sourceRoot":"","sources":["../../../src/utils/request/messages_data_options.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;;;CAoB5B,CAAA;AAED,eAAO,MAAM,kBAAkB,UAAmE,CAAA"}
@@ -1,5 +1,5 @@
1
1
  export const getMessageFields = {
2
- Message: ['text', 'text_edited_at', 'mine', 'attachments', 'created_at', 'deleted_at', 'author', 'reaction_counts', 'reply_count', 'reply_root', 'idempotent_key', 'message_type', 'person_ids_for_system_event', 'system_text_parts'],
2
+ Message: ['text', 'text_edited_at', 'mine', 'attachments', 'created_at', 'deleted_at', 'author', 'reaction_counts', 'reply_count', 'reply_root', 'idempotent_key', 'message_type', 'person_ids_for_system_event', 'system_text_parts', 'system_text_format'],
3
3
  Person: ['name', 'avatar'],
4
4
  ReactionCount: ['value', 'count', 'mine', 'message_id', 'author_ids']
5
5
  };
@@ -1 +1 @@
1
- {"version":3,"file":"messages_data_options.js","names":["getMessageFields","Message","Person","ReactionCount","getMessagesInclude"],"sources":["../../../src/utils/request/messages_data_options.ts"],"sourcesContent":["export const getMessageFields = {\n Message: [\n 'text',\n 'text_edited_at',\n 'mine',\n 'attachments',\n 'created_at',\n 'deleted_at',\n 'author',\n 'reaction_counts',\n 'reply_count',\n 'reply_root',\n 'idempotent_key',\n 'message_type',\n 'person_ids_for_system_event',\n 'system_text_parts',\n ],\n Person: ['name', 'avatar'],\n ReactionCount: ['value', 'count', 'mine', 'message_id', 'author_ids'],\n}\n\nexport const getMessagesInclude = ['author', 'reaction_counts', 'reply_root', 'reply_root.author']\n"],"mappings":"AAAA,OAAO,MAAMA,gBAAgB,GAAG;EAC9BC,OAAO,EAAE,CACP,MAAM,EACN,gBAAgB,EAChB,MAAM,EACN,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,6BAA6B,EAC7B,mBAAmB,CACpB;EACDC,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;EAC1BC,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY;AACtE,CAAC;AAED,OAAO,MAAMC,kBAAkB,GAAG,CAAC,QAAQ,EAAE,iBAAiB,EAAE,YAAY,EAAE,mBAAmB,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"messages_data_options.js","names":["getMessageFields","Message","Person","ReactionCount","getMessagesInclude"],"sources":["../../../src/utils/request/messages_data_options.ts"],"sourcesContent":["export const getMessageFields = {\n Message: [\n 'text',\n 'text_edited_at',\n 'mine',\n 'attachments',\n 'created_at',\n 'deleted_at',\n 'author',\n 'reaction_counts',\n 'reply_count',\n 'reply_root',\n 'idempotent_key',\n 'message_type',\n 'person_ids_for_system_event',\n 'system_text_parts',\n 'system_text_format',\n ],\n Person: ['name', 'avatar'],\n ReactionCount: ['value', 'count', 'mine', 'message_id', 'author_ids'],\n}\n\nexport const getMessagesInclude = ['author', 'reaction_counts', 'reply_root', 'reply_root.author']\n"],"mappings":"AAAA,OAAO,MAAMA,gBAAgB,GAAG;EAC9BC,OAAO,EAAE,CACP,MAAM,EACN,gBAAgB,EAChB,MAAM,EACN,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,6BAA6B,EAC7B,mBAAmB,EACnB,oBAAoB,CACrB;EACDC,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;EAC1BC,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY;AACtE,CAAC;AAED,OAAO,MAAMC,kBAAkB,GAAG,CAAC,QAAQ,EAAE,iBAAiB,EAAE,YAAY,EAAE,mBAAmB,CAAC","ignoreList":[]}
@@ -1,8 +1,6 @@
1
1
  import type { MessageResource } from '../types';
2
- declare const SYSTEM_MESSAGE_TYPES: readonly ["user_joined"];
3
- type SystemMessageType = (typeof SYSTEM_MESSAGE_TYPES)[number];
4
- export interface SystemMessageResource extends MessageResource {
5
- messageType: SystemMessageType;
2
+ export interface PeopleSystemMessageResource extends MessageResource {
3
+ systemTextFormat: 'people';
6
4
  systemTextParts: {
7
5
  names: string[];
8
6
  overflowCount: number;
@@ -10,6 +8,10 @@ export interface SystemMessageResource extends MessageResource {
10
8
  };
11
9
  personIdsForSystemEvent: number[];
12
10
  }
11
+ export interface ActorSystemMessageResource extends MessageResource {
12
+ systemTextFormat: 'actor';
13
+ text: string;
14
+ }
15
+ export type SystemMessageResource = PeopleSystemMessageResource | ActorSystemMessageResource;
13
16
  export declare const isSystemMessage: (message: MessageResource) => message is SystemMessageResource;
14
- export {};
15
17
  //# sourceMappingURL=system_messages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"system_messages.d.ts","sourceRoot":"","sources":["../../src/utils/system_messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,QAAA,MAAM,oBAAoB,0BAA2B,CAAA;AAErD,KAAK,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE9D,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D,WAAW,EAAE,iBAAiB,CAAA;IAC9B,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3E,uBAAuB,EAAE,MAAM,EAAE,CAAA;CAClC;AAED,eAAO,MAAM,eAAe,GAAI,SAAS,eAAe,KAAG,OAAO,IAAI,qBAG7B,CAAA"}
1
+ {"version":3,"file":"system_messages.d.ts","sourceRoot":"","sources":["../../src/utils/system_messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,MAAM,WAAW,2BAA4B,SAAQ,eAAe;IAClE,gBAAgB,EAAE,QAAQ,CAAA;IAC1B,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3E,uBAAuB,EAAE,MAAM,EAAE,CAAA;CAClC;AAED,MAAM,WAAW,0BAA2B,SAAQ,eAAe;IACjE,gBAAgB,EAAE,OAAO,CAAA;IACzB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,MAAM,qBAAqB,GAAG,2BAA2B,GAAG,0BAA0B,CAAA;AAE5F,eAAO,MAAM,eAAe,GAAI,SAAS,eAAe,KAAG,OAAO,IAAI,qBASrE,CAAA"}
@@ -1,3 +1,11 @@
1
- const SYSTEM_MESSAGE_TYPES = ['user_joined'];
2
- export const isSystemMessage = message => SYSTEM_MESSAGE_TYPES.includes(message.messageType) && message.systemTextParts != null && message.personIdsForSystemEvent != null;
1
+ export const isSystemMessage = message => {
2
+ switch (message.systemTextFormat) {
3
+ case 'people':
4
+ return message.systemTextParts != null && message.personIdsForSystemEvent != null;
5
+ case 'actor':
6
+ return !!message.text;
7
+ default:
8
+ return false;
9
+ }
10
+ };
3
11
  //# sourceMappingURL=system_messages.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"system_messages.js","names":["SYSTEM_MESSAGE_TYPES","isSystemMessage","message","includes","messageType","systemTextParts","personIdsForSystemEvent"],"sources":["../../src/utils/system_messages.ts"],"sourcesContent":["import type { MessageResource } from '../types'\n\nconst SYSTEM_MESSAGE_TYPES = ['user_joined'] as const\n\ntype SystemMessageType = (typeof SYSTEM_MESSAGE_TYPES)[number]\n\nexport interface SystemMessageResource extends MessageResource {\n messageType: SystemMessageType\n systemTextParts: { names: string[]; overflowCount: number; action: string }\n personIdsForSystemEvent: number[]\n}\n\nexport const isSystemMessage = (message: MessageResource): message is SystemMessageResource =>\n SYSTEM_MESSAGE_TYPES.includes(message.messageType as SystemMessageType) &&\n message.systemTextParts != null &&\n message.personIdsForSystemEvent != null\n"],"mappings":"AAEA,MAAMA,oBAAoB,GAAG,CAAC,aAAa,CAAU;AAUrD,OAAO,MAAMC,eAAe,GAAIC,OAAwB,IACtDF,oBAAoB,CAACG,QAAQ,CAACD,OAAO,CAACE,WAAgC,CAAC,IACvEF,OAAO,CAACG,eAAe,IAAI,IAAI,IAC/BH,OAAO,CAACI,uBAAuB,IAAI,IAAI","ignoreList":[]}
1
+ {"version":3,"file":"system_messages.js","names":["isSystemMessage","message","systemTextFormat","systemTextParts","personIdsForSystemEvent","text"],"sources":["../../src/utils/system_messages.ts"],"sourcesContent":["import type { MessageResource } from '../types'\n\nexport interface PeopleSystemMessageResource extends MessageResource {\n systemTextFormat: 'people'\n systemTextParts: { names: string[]; overflowCount: number; action: string }\n personIdsForSystemEvent: number[]\n}\n\nexport interface ActorSystemMessageResource extends MessageResource {\n systemTextFormat: 'actor'\n text: string\n}\n\nexport type SystemMessageResource = PeopleSystemMessageResource | ActorSystemMessageResource\n\nexport const isSystemMessage = (message: MessageResource): message is SystemMessageResource => {\n switch (message.systemTextFormat) {\n case 'people':\n return message.systemTextParts != null && message.personIdsForSystemEvent != null\n case 'actor':\n return !!message.text\n default:\n return false\n }\n}\n"],"mappings":"AAeA,OAAO,MAAMA,eAAe,GAAIC,OAAwB,IAAuC;EAC7F,QAAQA,OAAO,CAACC,gBAAgB;IAC9B,KAAK,QAAQ;MACX,OAAOD,OAAO,CAACE,eAAe,IAAI,IAAI,IAAIF,OAAO,CAACG,uBAAuB,IAAI,IAAI;IACnF,KAAK,OAAO;MACV,OAAO,CAAC,CAACH,OAAO,CAACI,IAAI;IACvB;MACE,OAAO,KAAK;EAChB;AACF,CAAC","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "4.4.1-qa-staging.8",
3
+ "version": "4.4.1-qa-staging.10",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,7 +33,7 @@
33
33
  "dependencies": {
34
34
  "@fortawesome/fontawesome-svg-core": "^7.2.0",
35
35
  "@fortawesome/react-native-fontawesome": "^0.3.2",
36
- "@planningcenter/emoji-keyboard": "4.4.1-qa-staging.8",
36
+ "@planningcenter/emoji-keyboard": "4.4.1-qa-staging.10",
37
37
  "lodash-inflection": "^1.5.0"
38
38
  },
39
39
  "peerDependencies": {
@@ -84,5 +84,5 @@
84
84
  "sf-symbols-typescript": "^2.2.0",
85
85
  "typescript": "~6.0.3"
86
86
  },
87
- "gitHead": "99dd70ff43acab9e20bf972700efaee7a3fa5b1c"
87
+ "gitHead": "1e3d2b7deafd780d4651c8da8adc7083ff348c3d"
88
88
  }
@@ -0,0 +1,42 @@
1
+ import { QueryClientProvider } from '@tanstack/react-query'
2
+ import { renderHook } from '@testing-library/react-native'
3
+ import React from 'react'
4
+ import { buildTestQueryClient } from '../../__utils__/query_client'
5
+ import { useFilterDropdownEnabled } from '../../hooks/use_filter_dropdown_enabled'
6
+ import { getFeaturesQueryKey } from '../../utils/request/get_features'
7
+
8
+ jest.mock('../../hooks/use_api_client')
9
+
10
+ const renderWithFeatures = (enabledFlags: string[]) => {
11
+ const queryClient = buildTestQueryClient()
12
+ queryClient.setQueryData(getFeaturesQueryKey(), {
13
+ data: enabledFlags.map((name, index) => ({
14
+ type: 'Feature',
15
+ id: `${index}`,
16
+ name,
17
+ enabled: true,
18
+ })),
19
+ links: {},
20
+ meta: { count: enabledFlags.length, totalCount: enabledFlags.length },
21
+ })
22
+
23
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
24
+ <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
25
+ )
26
+
27
+ return renderHook(() => useFilterDropdownEnabled(), { wrapper })
28
+ }
29
+
30
+ describe('useFilterDropdownEnabled', () => {
31
+ it('is on under QA_MOBILE_filter_dropdown', () => {
32
+ expect(renderWithFeatures(['QA_MOBILE_filter_dropdown']).result.current).toBe(true)
33
+ })
34
+
35
+ it('is on under ROLLOUT_MOBILE_filter_dropdown', () => {
36
+ expect(renderWithFeatures(['ROLLOUT_MOBILE_filter_dropdown']).result.current).toBe(true)
37
+ })
38
+
39
+ it('is off when neither flag is on', () => {
40
+ expect(renderWithFeatures(['ROLLOUT_WEB_filter_dropdown']).result.current).toBe(false)
41
+ })
42
+ })
@@ -18,62 +18,49 @@ const makeMessage = (overrides: Partial<MessageResource> = {}): MessageResource
18
18
  messageType: 'user',
19
19
  personIdsForSystemEvent: null,
20
20
  systemTextParts: null,
21
+ systemTextFormat: null,
21
22
  ...overrides,
22
23
  })
23
24
 
25
+ const joinedParts = { names: ['Alice'], overflowCount: 0, action: 'joined the conversation' }
26
+
24
27
  describe('isSystemMessage', () => {
25
- it('returns true for user_joined messages', () => {
28
+ it('returns true for people messages with names and person ids', () => {
26
29
  const message = makeMessage({
27
30
  messageType: 'user_joined',
31
+ systemTextFormat: 'people',
28
32
  personIdsForSystemEvent: [1],
29
- systemTextParts: { names: ['Alice'], overflowCount: 0, action: 'joined the conversation' },
33
+ systemTextParts: joinedParts,
30
34
  })
31
35
  expect(isSystemMessage(message)).toBe(true)
32
36
  })
33
37
 
34
- it('narrows the type so systemTextParts and personIdsForSystemEvent are non-null', () => {
38
+ it('returns true for actor messages of a type the client does not know', () => {
35
39
  const message = makeMessage({
36
- messageType: 'user_joined',
37
- personIdsForSystemEvent: [1, 2],
38
- systemTextParts: {
39
- names: ['Alice', 'Bob'],
40
- overflowCount: 0,
41
- action: 'joined the conversation',
42
- },
40
+ messageType: 'some_future_type',
41
+ systemTextFormat: 'actor',
42
+ text: 'This conversation was archived by Alice',
43
43
  })
44
- if (isSystemMessage(message)) {
45
- expect(message.systemTextParts.names).toEqual(['Alice', 'Bob'])
46
- expect(message.personIdsForSystemEvent).toEqual([1, 2])
47
- } else {
48
- throw new Error('Expected isSystemMessage to return true')
49
- }
44
+ expect(isSystemMessage(message)).toBe(true)
50
45
  })
51
46
 
52
- it('returns false for regular user messages', () => {
53
- const message = makeMessage({ messageType: 'user' })
47
+ it('returns false for messages without a system text format', () => {
48
+ const message = makeMessage({ messageType: 'user_joined', systemTextParts: joinedParts })
54
49
  expect(isSystemMessage(message)).toBe(false)
55
50
  })
56
51
 
57
- it('returns false for unknown message types', () => {
58
- const message = makeMessage({ messageType: 'some_future_type' })
52
+ it('returns false for people messages without systemTextParts', () => {
53
+ const message = makeMessage({ systemTextFormat: 'people', personIdsForSystemEvent: [1] })
59
54
  expect(isSystemMessage(message)).toBe(false)
60
55
  })
61
56
 
62
- it('returns false when systemTextParts is null', () => {
63
- const message = makeMessage({
64
- messageType: 'user_joined',
65
- personIdsForSystemEvent: [1],
66
- systemTextParts: null,
67
- })
57
+ it('returns false for people messages without personIdsForSystemEvent', () => {
58
+ const message = makeMessage({ systemTextFormat: 'people', systemTextParts: joinedParts })
68
59
  expect(isSystemMessage(message)).toBe(false)
69
60
  })
70
61
 
71
- it('returns false when personIdsForSystemEvent is null', () => {
72
- const message = makeMessage({
73
- messageType: 'user_joined',
74
- personIdsForSystemEvent: null,
75
- systemTextParts: { names: ['Alice'], overflowCount: 0, action: 'joined the conversation' },
76
- })
62
+ it.each([null, ''])('returns false for actor messages with text %p', text => {
63
+ const message = makeMessage({ systemTextFormat: 'actor', text })
77
64
  expect(isSystemMessage(message)).toBe(false)
78
65
  })
79
66
  })
@@ -0,0 +1,104 @@
1
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
2
+ import { render } from '@testing-library/react-native'
3
+ import React from 'react'
4
+ import { buildTestQueryClient } from '../../../__utils__/query_client'
5
+ import { ChatProvider } from '../../../contexts/chat_context'
6
+ import type { PersonResource } from '../../../types/resources/person'
7
+ import type { SystemMessageResource } from '../../../utils/system_messages'
8
+ import { SystemMessage } from '../system_message'
9
+
10
+ jest.mock('@react-navigation/native', () => ({
11
+ useNavigation: () => ({ navigate: jest.fn() }),
12
+ }))
13
+ jest.mock('../../../hooks/use_animated_message_background_color', () => ({
14
+ useAnimatedMessageBackgroundColor: () => ({
15
+ animatedBackgroundColor: {},
16
+ handleMessagePressIn: jest.fn(),
17
+ handleMessagePressOut: jest.fn(),
18
+ }),
19
+ }))
20
+
21
+ const author = { id: 1, type: 'Person', name: 'Wes', avatar: null } as unknown as PersonResource
22
+
23
+ const systemMessage = (overrides: Partial<SystemMessageResource>): SystemMessageResource =>
24
+ ({
25
+ type: 'Message',
26
+ id: '01',
27
+ text: null,
28
+ html: '',
29
+ createdAt: '2026-02-03T14:18:00',
30
+ deletedAt: null,
31
+ textEditedAt: null,
32
+ mine: false,
33
+ attachments: [],
34
+ author,
35
+ reactionCounts: [],
36
+ replyCount: 0,
37
+ replyRootId: null,
38
+ messageType: 'user_joined',
39
+ personIdsForSystemEvent: null,
40
+ systemTextParts: null,
41
+ ...overrides,
42
+ }) as SystemMessageResource
43
+
44
+ let queryClient: QueryClient
45
+
46
+ const Wrapper = ({ children }: { children: React.ReactNode }) => (
47
+ <QueryClientProvider client={queryClient}>
48
+ <ChatProvider
49
+ value={{
50
+ token: {
51
+ access_token: '',
52
+ created_at: 0,
53
+ expires_in: 0,
54
+ scope: '',
55
+ refresh_token: '',
56
+ token_type: '',
57
+ },
58
+ onUnauthorizedResponse: () => {},
59
+ theme: { theme: { colors: { interaction: 'rgb(0, 0, 255)' } } },
60
+ }}
61
+ >
62
+ {children}
63
+ </ChatProvider>
64
+ </QueryClientProvider>
65
+ )
66
+
67
+ const renderSystemMessage = (message: SystemMessageResource) =>
68
+ render(<SystemMessage message={message} conversationId={1} />, { wrapper: Wrapper })
69
+
70
+ beforeEach(() => {
71
+ jest.useFakeTimers({ now: new Date(2026, 5, 15, 12, 0) })
72
+ queryClient = buildTestQueryClient()
73
+ })
74
+
75
+ afterEach(() => {
76
+ queryClient.clear()
77
+ jest.useRealTimers()
78
+ })
79
+
80
+ describe('SystemMessage', () => {
81
+ it('renders actor messages as their text followed by the local date and time', () => {
82
+ const view = renderSystemMessage(
83
+ systemMessage({
84
+ messageType: 'conversation_archived',
85
+ systemTextFormat: 'actor',
86
+ text: 'This conversation was archived by Wes',
87
+ })
88
+ )
89
+
90
+ expect(view.getByText('This conversation was archived by Wes on Feb 3 at 2:18pm')).toBeTruthy()
91
+ })
92
+
93
+ it('builds people messages from their names', () => {
94
+ const view = renderSystemMessage(
95
+ systemMessage({
96
+ systemTextFormat: 'people',
97
+ systemTextParts: { names: ['Ann', 'Bo'], overflowCount: 0, action: 'joined' },
98
+ personIdsForSystemEvent: [1, 2],
99
+ })
100
+ )
101
+
102
+ expect(view.getByText('Ann and Bo joined')).toBeTruthy()
103
+ })
104
+ })
@@ -4,6 +4,7 @@ import { Pressable, StyleSheet, View } from 'react-native'
4
4
  import Animated from 'react-native-reanimated'
5
5
  import { useAnimatedMessageBackgroundColor, useTheme } from '../../hooks'
6
6
  import { ReactionCountResource } from '../../types/resources/reaction'
7
+ import { formatEventDateTime } from '../../utils/date'
7
8
  import { Haptic } from '../../utils/native_adapters'
8
9
  import { SystemMessageResource } from '../../utils/system_messages'
9
10
  import { Text } from '../display'
@@ -15,21 +16,23 @@ interface SystemMessageProps {
15
16
  }
16
17
 
17
18
  export function SystemMessage({ message, conversationId }: SystemMessageProps) {
18
- const { reactionCounts, systemTextParts, personIdsForSystemEvent } = message
19
- const { names, overflowCount, action } = systemTextParts
19
+ const { reactionCounts } = message
20
20
  const styles = useStyles()
21
21
  const navigation = useNavigation()
22
22
  const { colors } = useTheme()
23
- const text = systemMessageText(names, overflowCount, action)
24
- const isTruncated = overflowCount > 0
23
+ const text = systemMessageText(message)
24
+ const isTruncated =
25
+ message.systemTextFormat === 'people' && message.systemTextParts.overflowCount > 0
25
26
  const hasReactions = reactionCounts.length > 0
26
27
  const { animatedBackgroundColor, handleMessagePressIn, handleMessagePressOut } =
27
28
  useAnimatedMessageBackgroundColor()
28
29
 
29
30
  const handlePress = () => {
31
+ if (message.systemTextFormat !== 'people') return
32
+
30
33
  navigation.navigate('SystemMessagePeople', {
31
34
  conversation_id: conversationId,
32
- person_ids: personIdsForSystemEvent,
35
+ person_ids: message.personIdsForSystemEvent,
33
36
  })
34
37
  }
35
38
 
@@ -87,7 +90,18 @@ export function SystemMessage({ message, conversationId }: SystemMessageProps) {
87
90
  )
88
91
  }
89
92
 
90
- function systemMessageText(names: string[], overflowCount: number, action: string): string {
93
+ function systemMessageText(message: SystemMessageResource): string {
94
+ switch (message.systemTextFormat) {
95
+ case 'people': {
96
+ const { names, overflowCount, action } = message.systemTextParts
97
+ return peopleSystemMessageText(names, overflowCount, action)
98
+ }
99
+ case 'actor':
100
+ return `${message.text} on ${formatEventDateTime(message.createdAt)}`
101
+ }
102
+ }
103
+
104
+ function peopleSystemMessageText(names: string[], overflowCount: number, action: string): string {
91
105
  if (overflowCount > 0) {
92
106
  const overflowLabel = `${overflowCount} ${overflowCount === 1 ? 'other' : 'others'}`
93
107
  return `${names.join(', ')}, and ${overflowLabel} ${action}`