@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.
- package/build/components/conversation/system_message.d.ts.map +1 -1
- package/build/components/conversation/system_message.js +85 -74
- package/build/components/conversation/system_message.js.map +1 -1
- package/build/components/conversations/conversation_preview.js +2 -0
- package/build/components/conversations/conversation_preview.js.map +1 -1
- package/build/hooks/use_features.d.ts +2 -0
- package/build/hooks/use_features.d.ts.map +1 -1
- package/build/hooks/use_features.js +2 -0
- package/build/hooks/use_features.js.map +1 -1
- package/build/hooks/use_filter_dropdown_enabled.d.ts +2 -0
- package/build/hooks/use_filter_dropdown_enabled.d.ts.map +1 -0
- package/build/hooks/use_filter_dropdown_enabled.js +18 -0
- package/build/hooks/use_filter_dropdown_enabled.js.map +1 -0
- package/build/types/jolt_events/message_events.d.ts +2 -0
- package/build/types/jolt_events/message_events.d.ts.map +1 -1
- package/build/types/jolt_events/message_events.js.map +1 -1
- package/build/types/resources/conversation.d.ts +1 -1
- package/build/types/resources/conversation.d.ts.map +1 -1
- package/build/types/resources/conversation.js.map +1 -1
- package/build/types/resources/message.d.ts +2 -0
- package/build/types/resources/message.d.ts.map +1 -1
- package/build/types/resources/message.js.map +1 -1
- package/build/utils/date.d.ts +1 -0
- package/build/utils/date.d.ts.map +1 -1
- package/build/utils/date.js +15 -1
- package/build/utils/date.js.map +1 -1
- package/build/utils/jolt/transform_message_event_data_to_message_resource.d.ts.map +1 -1
- package/build/utils/jolt/transform_message_event_data_to_message_resource.js +2 -1
- package/build/utils/jolt/transform_message_event_data_to_message_resource.js.map +1 -1
- package/build/utils/request/messages_data_options.d.ts.map +1 -1
- package/build/utils/request/messages_data_options.js +1 -1
- package/build/utils/request/messages_data_options.js.map +1 -1
- package/build/utils/system_messages.d.ts +7 -5
- package/build/utils/system_messages.d.ts.map +1 -1
- package/build/utils/system_messages.js +10 -2
- package/build/utils/system_messages.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/hooks/use_filter_dropdown_enabled.test.tsx +42 -0
- package/src/__tests__/utils/system_messages.ts +19 -32
- package/src/components/conversation/__tests__/system_message.test.tsx +104 -0
- package/src/components/conversation/system_message.tsx +20 -6
- package/src/components/conversations/__tests__/conversation_preview.test.tsx +70 -0
- package/src/components/conversations/conversation_preview.tsx +4 -0
- package/src/hooks/use_features.ts +2 -0
- package/src/hooks/use_filter_dropdown_enabled.ts +10 -0
- package/src/types/jolt_events/message_events.ts +2 -0
- package/src/types/resources/conversation.ts +1 -1
- package/src/types/resources/message.ts +3 -0
- package/src/utils/__tests__/date.test.ts +19 -0
- package/src/utils/__tests__/group_messages.test.ts +1 -0
- package/src/utils/date.ts +8 -1
- package/src/utils/jolt/__tests__/transform_message_event_data_to_message_resource.test.ts +35 -0
- package/src/utils/jolt/transform_message_event_data_to_message_resource.ts +1 -0
- package/src/utils/request/messages_data_options.ts +1 -0
- 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;
|
|
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;
|
|
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":[]}
|
package/build/utils/date.d.ts
CHANGED
|
@@ -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"}
|
package/build/utils/date.js
CHANGED
|
@@ -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
|
package/build/utils/date.js.map
CHANGED
|
@@ -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;
|
|
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,
|
|
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;
|
|
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;;;;
|
|
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,
|
|
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
|
-
|
|
3
|
-
|
|
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,
|
|
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
|
|
2
|
-
|
|
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":["
|
|
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.
|
|
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.
|
|
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": "
|
|
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
|
|
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:
|
|
33
|
+
systemTextParts: joinedParts,
|
|
30
34
|
})
|
|
31
35
|
expect(isSystemMessage(message)).toBe(true)
|
|
32
36
|
})
|
|
33
37
|
|
|
34
|
-
it('
|
|
38
|
+
it('returns true for actor messages of a type the client does not know', () => {
|
|
35
39
|
const message = makeMessage({
|
|
36
|
-
messageType: '
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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
|
|
53
|
-
const message = makeMessage({ messageType: '
|
|
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
|
|
58
|
-
const message = makeMessage({
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
24
|
-
const isTruncated =
|
|
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(
|
|
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}`
|