@planningcenter/chat-react-native 3.11.0-rc.8 → 3.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/conversation/attachments/image_attachment.d.ts.map +1 -1
- package/build/components/conversation/attachments/image_attachment.js +9 -2
- package/build/components/conversation/attachments/image_attachment.js.map +1 -1
- package/build/components/conversation/message.d.ts +1 -1
- package/build/components/conversation/message.d.ts.map +1 -1
- package/build/components/conversation/message.js +85 -26
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/message_form/message_form_attachment_image.d.ts +1 -1
- package/build/components/conversation/message_form/message_form_attachment_image.d.ts.map +1 -1
- package/build/components/conversation/message_form/message_form_attachment_image.js.map +1 -1
- package/build/components/conversation/message_form/message_form_attachment_video.d.ts +1 -1
- package/build/components/conversation/message_form/message_form_attachment_video.d.ts.map +1 -1
- package/build/components/conversation/message_form/message_form_attachment_video.js.map +1 -1
- package/build/components/conversation/message_form.d.ts.map +1 -1
- package/build/components/conversation/message_form.js +12 -10
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/components/conversations/conversations.d.ts.map +1 -1
- package/build/components/conversations/conversations.js +5 -1
- package/build/components/conversations/conversations.js.map +1 -1
- package/build/components/display/spinner.d.ts +6 -1
- package/build/components/display/spinner.d.ts.map +1 -1
- package/build/components/display/spinner.js +2 -2
- package/build/components/display/spinner.js.map +1 -1
- package/build/components/display/text.js +10 -2
- package/build/components/display/text.js.map +1 -1
- package/build/components/primitive/form_sheet.d.ts +1 -0
- package/build/components/primitive/form_sheet.d.ts.map +1 -1
- package/build/components/primitive/form_sheet.js +2 -2
- package/build/components/primitive/form_sheet.js.map +1 -1
- package/build/contexts/api_provider.d.ts +1 -0
- package/build/contexts/api_provider.d.ts.map +1 -1
- package/build/contexts/api_provider.js +24 -2
- package/build/contexts/api_provider.js.map +1 -1
- package/build/hooks/groups/use_group_members_for_new_conversation.d.ts +1 -1
- package/build/hooks/groups/use_groups_conversation_create.d.ts.map +1 -1
- package/build/hooks/groups/use_groups_conversation_create.js +3 -1
- package/build/hooks/groups/use_groups_conversation_create.js.map +1 -1
- package/build/hooks/services/use_find_or_create_services_conversation.d.ts +2 -0
- package/build/hooks/services/use_find_or_create_services_conversation.d.ts.map +1 -1
- package/build/hooks/services/use_find_or_create_services_conversation.js +22 -19
- package/build/hooks/services/use_find_or_create_services_conversation.js.map +1 -1
- package/build/hooks/{use_services_team.d.ts → services/use_services_team.d.ts} +1 -1
- package/build/hooks/services/use_services_team.d.ts.map +1 -0
- package/build/hooks/{use_services_team.js → services/use_services_team.js} +1 -1
- package/build/hooks/services/use_services_team.js.map +1 -0
- package/build/hooks/use_attachment_uploader.d.ts +5 -13
- package/build/hooks/use_attachment_uploader.d.ts.map +1 -1
- package/build/hooks/use_attachment_uploader.js.map +1 -1
- package/build/hooks/use_chat_permissions.d.ts +10 -0
- package/build/hooks/use_chat_permissions.d.ts.map +1 -1
- package/build/hooks/use_chat_permissions.js +10 -9
- package/build/hooks/use_chat_permissions.js.map +1 -1
- package/build/hooks/use_conversation.d.ts +1 -1
- package/build/hooks/use_conversation_messages_jolt_events.d.ts.map +1 -1
- package/build/hooks/use_conversation_messages_jolt_events.js +16 -1
- package/build/hooks/use_conversation_messages_jolt_events.js.map +1 -1
- package/build/hooks/use_giphy.d.ts +1 -1
- package/build/hooks/use_giphy.d.ts.map +1 -1
- package/build/hooks/use_giphy.js.map +1 -1
- package/build/hooks/use_message_create_or_update.d.ts +8 -4
- package/build/hooks/use_message_create_or_update.d.ts.map +1 -1
- package/build/hooks/use_message_create_or_update.js +58 -4
- package/build/hooks/use_message_create_or_update.js.map +1 -1
- package/build/hooks/use_read_receipts.d.ts +1 -1
- package/build/hooks/use_suspense_api.d.ts +2 -2
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/navigation/index.d.ts +11 -0
- package/build/navigation/index.d.ts.map +1 -1
- package/build/navigation/index.js +10 -0
- package/build/navigation/index.js.map +1 -1
- package/build/screens/conversation_details_screen.js +1 -1
- package/build/screens/conversation_details_screen.js.map +1 -1
- package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.d.ts.map +1 -1
- package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.js +81 -17
- package/build/screens/conversation_filter_recipients/conversation_filter_recipients_screen.js.map +1 -1
- package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.d.ts +171 -4
- package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.d.ts.map +1 -1
- package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.js +49 -8
- package/build/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.js.map +1 -1
- package/build/screens/conversation_filter_recipients/types.d.ts +7 -0
- package/build/screens/conversation_filter_recipients/types.d.ts.map +1 -1
- package/build/screens/conversation_filter_recipients/types.js +6 -0
- package/build/screens/conversation_filter_recipients/types.js.map +1 -1
- package/build/screens/conversation_filters/components/rows.js +1 -1
- package/build/screens/conversation_filters/components/rows.js.map +1 -1
- package/build/screens/conversation_new/components/groups_form.js +2 -2
- package/build/screens/conversation_new/components/groups_form.js.map +1 -1
- package/build/screens/conversation_new/components/services_form.d.ts +3 -1
- package/build/screens/conversation_new/components/services_form.d.ts.map +1 -1
- package/build/screens/conversation_new/components/services_form.js +6 -5
- package/build/screens/conversation_new/components/services_form.js.map +1 -1
- package/build/screens/conversation_new/conversation_new_screen.d.ts +2 -0
- package/build/screens/conversation_new/conversation_new_screen.d.ts.map +1 -1
- package/build/screens/conversation_new/conversation_new_screen.js +2 -2
- package/build/screens/conversation_new/conversation_new_screen.js.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js +38 -33
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js.map +1 -1
- package/build/screens/team_conversation_screen.d.ts +8 -0
- package/build/screens/team_conversation_screen.d.ts.map +1 -0
- package/build/screens/team_conversation_screen.js +28 -0
- package/build/screens/team_conversation_screen.js.map +1 -0
- package/build/types/resources/denormalized_attachment_resource.d.ts +9 -32
- package/build/types/resources/denormalized_attachment_resource.d.ts.map +1 -1
- package/build/types/resources/denormalized_attachment_resource.js.map +1 -1
- package/build/types/resources/denormalized_attachment_resource_for_create.d.ts +50 -0
- package/build/types/resources/denormalized_attachment_resource_for_create.d.ts.map +1 -0
- package/build/types/resources/denormalized_attachment_resource_for_create.js +2 -0
- package/build/types/resources/denormalized_attachment_resource_for_create.js.map +1 -0
- package/build/types/resources/message.d.ts +4 -0
- package/build/types/resources/message.d.ts.map +1 -1
- package/build/types/resources/message.js.map +1 -1
- package/build/types/resources/services/chat_resource.d.ts +52 -0
- package/build/types/resources/services/chat_resource.d.ts.map +1 -0
- package/build/types/resources/services/chat_resource.js +7 -0
- package/build/types/resources/services/chat_resource.js.map +1 -0
- package/build/types/resources/services/index.d.ts +1 -0
- package/build/types/resources/services/index.d.ts.map +1 -1
- package/build/types/resources/services/index.js +1 -0
- package/build/types/resources/services/index.js.map +1 -1
- package/build/types/resources/services/team_resource.d.ts +9 -41
- package/build/types/resources/services/team_resource.d.ts.map +1 -1
- package/build/types/resources/services/team_resource.js +0 -5
- package/build/types/resources/services/team_resource.js.map +1 -1
- package/build/utils/cache/optimistically_create_message.d.ts +10 -0
- package/build/utils/cache/optimistically_create_message.d.ts.map +1 -0
- package/build/utils/cache/optimistically_create_message.js +43 -0
- package/build/utils/cache/optimistically_create_message.js.map +1 -0
- package/build/utils/cache/optimistically_update_message.d.ts +7 -0
- package/build/utils/cache/optimistically_update_message.d.ts.map +1 -0
- package/build/utils/cache/optimistically_update_message.js +21 -0
- package/build/utils/cache/optimistically_update_message.js.map +1 -0
- package/build/utils/cache/page_mutations.d.ts +6 -3
- package/build/utils/cache/page_mutations.d.ts.map +1 -1
- package/build/utils/cache/page_mutations.js +4 -4
- package/build/utils/cache/page_mutations.js.map +1 -1
- package/build/utils/convert_attachments_for_create.d.ts +12 -0
- package/build/utils/convert_attachments_for_create.d.ts.map +1 -0
- package/build/utils/convert_attachments_for_create.js +70 -0
- package/build/utils/convert_attachments_for_create.js.map +1 -0
- package/build/utils/generate_placeholder_ulid.d.ts +10 -0
- package/build/utils/generate_placeholder_ulid.d.ts.map +1 -0
- package/build/utils/generate_placeholder_ulid.js +28 -0
- package/build/utils/generate_placeholder_ulid.js.map +1 -0
- package/build/utils/index.d.ts +1 -0
- package/build/utils/index.d.ts.map +1 -1
- package/build/utils/index.js +1 -0
- package/build/utils/index.js.map +1 -1
- package/build/utils/response_error.d.ts +1 -0
- package/build/utils/response_error.d.ts.map +1 -1
- package/build/utils/response_error.js +6 -0
- package/build/utils/response_error.js.map +1 -1
- package/package.json +2 -2
- package/src/components/conversation/attachments/image_attachment.tsx +25 -10
- package/src/components/conversation/message.tsx +116 -28
- package/src/components/conversation/message_form/message_form_attachment_image.tsx +1 -1
- package/src/components/conversation/message_form/message_form_attachment_video.tsx +1 -1
- package/src/components/conversation/message_form.tsx +16 -13
- package/src/components/conversations/conversations.tsx +8 -1
- package/src/components/display/spinner.tsx +7 -2
- package/src/components/display/text.tsx +10 -2
- package/src/components/primitive/form_sheet.tsx +3 -2
- package/src/contexts/api_provider.tsx +37 -3
- package/src/hooks/groups/use_groups_conversation_create.ts +3 -1
- package/src/hooks/services/use_find_or_create_services_conversation.ts +29 -21
- package/src/hooks/{use_services_team.ts → services/use_services_team.ts} +2 -2
- package/src/hooks/use_attachment_uploader.ts +9 -25
- package/src/hooks/use_chat_permissions.ts +12 -9
- package/src/hooks/use_conversation_messages_jolt_events.ts +19 -1
- package/src/hooks/use_giphy.ts +1 -1
- package/src/hooks/use_message_create_or_update.ts +82 -6
- package/src/index.tsx +1 -1
- package/src/navigation/index.tsx +10 -0
- package/src/screens/conversation_details_screen.tsx +1 -1
- package/src/screens/conversation_filter_recipients/conversation_filter_recipients_screen.tsx +118 -17
- package/src/screens/conversation_filter_recipients/hooks/use_service_types_with_teams.ts +61 -10
- package/src/screens/conversation_filter_recipients/types.tsx +8 -0
- package/src/screens/conversation_filters/components/rows.tsx +1 -1
- package/src/screens/conversation_new/components/groups_form.tsx +2 -2
- package/src/screens/conversation_new/components/services_form.tsx +17 -3
- package/src/screens/conversation_new/conversation_new_screen.tsx +11 -2
- package/src/screens/conversation_select_recipients/conversation_select_recipients_screen.tsx +90 -74
- package/src/screens/team_conversation_screen.tsx +46 -0
- package/src/types/resources/denormalized_attachment_resource.ts +9 -37
- package/src/types/resources/denormalized_attachment_resource_for_create.ts +65 -0
- package/src/types/resources/message.ts +6 -0
- package/src/types/resources/services/chat_resource.ts +66 -0
- package/src/types/resources/services/index.ts +1 -0
- package/src/types/resources/services/team_resource.ts +10 -53
- package/src/utils/__tests__/convert_attachments_for_create.test.ts +175 -0
- package/src/utils/cache/optimistically_create_message.ts +71 -0
- package/src/utils/cache/optimistically_update_message.ts +37 -0
- package/src/utils/cache/page_mutations.ts +5 -3
- package/src/utils/convert_attachments_for_create.ts +92 -0
- package/src/utils/generate_placeholder_ulid.ts +32 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/response_error.ts +8 -0
- package/build/hooks/use_services_team.d.ts.map +0 -1
- package/build/hooks/use_services_team.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate_placeholder_ulid.d.ts","sourceRoot":"","sources":["../../src/utils/generate_placeholder_ulid.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,wBAAgB,uBAAuB,CAAC,EAAE,QAAY,EAAE,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAa5F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The actual `ulid` library depends on a secure random number generator, which looks like it
|
|
3
|
+
* may require a native dependency to polyfill in React Native.
|
|
4
|
+
* Since this is only used as a local temporary ID, I think we can get away with a simpler
|
|
5
|
+
* implementation that doesn't require any native dependencies.
|
|
6
|
+
*/
|
|
7
|
+
const ULID_CHARS = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; // Crockford's Base32
|
|
8
|
+
function encodeBase32(value, length) {
|
|
9
|
+
let result = '';
|
|
10
|
+
for (let i = 0; i < length; i++) {
|
|
11
|
+
result = ULID_CHARS[value % 32] + result;
|
|
12
|
+
value = Math.floor(value / 32);
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
export function generatePlaceholderUlid({ offsetMs = 0 } = {}) {
|
|
17
|
+
const timestamp = Date.now() + offsetMs; // Milliseconds since epoch
|
|
18
|
+
// 48 bits for timestamp (6 Base32 characters)
|
|
19
|
+
const timeComponent = encodeBase32(timestamp, 10); // 48 bits = 6 bytes = 10 Base32 characters (approx, needs more precise bit shifting)
|
|
20
|
+
// 80 bits for randomness (16 Base32 characters)
|
|
21
|
+
let randomComponent = '';
|
|
22
|
+
for (let i = 0; i < 16; i++) {
|
|
23
|
+
// Generate 16 random Base32 chars
|
|
24
|
+
randomComponent += ULID_CHARS[Math.floor(Math.random() * 32)];
|
|
25
|
+
}
|
|
26
|
+
return timeComponent + randomComponent;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=generate_placeholder_ulid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate_placeholder_ulid.js","sourceRoot":"","sources":["../../src/utils/generate_placeholder_ulid.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,UAAU,GAAG,kCAAkC,CAAA,CAAC,qBAAqB;AAE3E,SAAS,YAAY,CAAC,KAAa,EAAE,MAAc;IACjD,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,GAAG,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,MAAM,CAAA;QACxC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAA;IAChC,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,EAAE,QAAQ,GAAG,CAAC,KAA4B,EAAE;IAClF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAA,CAAC,2BAA2B;IACnE,8CAA8C;IAC9C,MAAM,aAAa,GAAG,YAAY,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA,CAAC,qFAAqF;IAEvI,gDAAgD;IAChD,IAAI,eAAe,GAAG,EAAE,CAAA;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,kCAAkC;QAClC,eAAe,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;IAC/D,CAAC;IAED,OAAO,aAAa,GAAG,eAAe,CAAA;AACxC,CAAC","sourcesContent":["/**\n * The actual `ulid` library depends on a secure random number generator, which looks like it\n * may require a native dependency to polyfill in React Native.\n * Since this is only used as a local temporary ID, I think we can get away with a simpler\n * implementation that doesn't require any native dependencies.\n */\n\nconst ULID_CHARS = '0123456789ABCDEFGHJKMNPQRSTVWXYZ' // Crockford's Base32\n\nfunction encodeBase32(value: number, length: number) {\n let result = ''\n for (let i = 0; i < length; i++) {\n result = ULID_CHARS[value % 32] + result\n value = Math.floor(value / 32)\n }\n return result\n}\n\nexport function generatePlaceholderUlid({ offsetMs = 0 }: { offsetMs?: number } = {}): string {\n const timestamp = Date.now() + offsetMs // Milliseconds since epoch\n // 48 bits for timestamp (6 Base32 characters)\n const timeComponent = encodeBase32(timestamp, 10) // 48 bits = 6 bytes = 10 Base32 characters (approx, needs more precise bit shifting)\n\n // 80 bits for randomness (16 Base32 characters)\n let randomComponent = ''\n for (let i = 0; i < 16; i++) {\n // Generate 16 random Base32 chars\n randomComponent += ULID_CHARS[Math.floor(Math.random() * 32)]\n }\n\n return timeComponent + randomComponent\n}\n"]}
|
package/build/utils/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,mCAAmC,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,mCAAmC,CAAA;AACjD,cAAc,kCAAkC,CAAA"}
|
package/build/utils/index.js
CHANGED
package/build/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,mCAAmC,CAAA","sourcesContent":["export * from './session'\nexport * from './theme'\nexport * from './styles'\nexport * from './space'\nexport * from './client'\nexport * from './uri'\nexport * from './cache'\nexport * from './native_adapters'\nexport * from './pluralize'\nexport * from './destructure_chat_group_graph_id'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,mCAAmC,CAAA;AACjD,cAAc,kCAAkC,CAAA","sourcesContent":["export * from './session'\nexport * from './theme'\nexport * from './styles'\nexport * from './space'\nexport * from './client'\nexport * from './uri'\nexport * from './cache'\nexport * from './native_adapters'\nexport * from './pluralize'\nexport * from './destructure_chat_group_graph_id'\nexport * from './convert_attachments_for_create'\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response_error.d.ts","sourceRoot":"","sources":["../../src/utils/response_error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAElD,qBAAa,aAAc,SAAQ,KAAK;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAC1B,QAAQ,EAAE,QAAQ,CAAA;gBAEN,QAAQ,EAAE,QAAQ;CAQ/B"}
|
|
1
|
+
{"version":3,"file":"response_error.d.ts","sourceRoot":"","sources":["../../src/utils/response_error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAElD,qBAAa,aAAc,SAAQ,KAAK;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAC1B,QAAQ,EAAE,QAAQ,CAAA;gBAEN,QAAQ,EAAE,QAAQ;CAQ/B;AAED,eAAO,MAAM,kBAAkB,UAAW,OAAO,mBAMhD,CAAA"}
|
|
@@ -12,4 +12,10 @@ export class ResponseError extends Error {
|
|
|
12
12
|
this.response = response;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
+
export const throwResponseError = (error) => {
|
|
16
|
+
if (error instanceof Response) {
|
|
17
|
+
throw new ResponseError(error);
|
|
18
|
+
}
|
|
19
|
+
return Promise.reject(error);
|
|
20
|
+
};
|
|
15
21
|
//# sourceMappingURL=response_error.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response_error.js","sourceRoot":"","sources":["../../src/utils/response_error.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,MAAM,CAAQ;IACd,UAAU,CAAQ;IAClB,MAAM,CAAoB;IAC1B,QAAQ,CAAU;IAElB,YAAY,QAAkB;QAC5B,KAAK,CAAC,kBAAkB,QAAQ,EAAE,MAAM,IAAI,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAA;QACnE,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;QAC3B,IAAI,CAAC,MAAM,GAAG,QAAQ,EAAE,MAAM,CAAA;QAC9B,IAAI,CAAC,UAAU,GAAG,QAAQ,EAAE,UAAU,CAAA;QACtC,IAAI,CAAC,MAAM,GAAG,QAAQ,EAAE,MAAM,IAAI,EAAE,CAAA;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;CACF","sourcesContent":["import { ApiError } from '../types/api_primitives'\n\nexport class ResponseError extends Error {\n status: number\n statusText: string\n errors: ApiError['errors']\n response: ApiError\n\n constructor(response: ApiError) {\n super(`ResponseError: ${response?.status} ${response?.statusText}`)\n this.name = 'ResponseError'\n this.status = response?.status\n this.statusText = response?.statusText\n this.errors = response?.errors || []\n this.response = response\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"response_error.js","sourceRoot":"","sources":["../../src/utils/response_error.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,MAAM,CAAQ;IACd,UAAU,CAAQ;IAClB,MAAM,CAAoB;IAC1B,QAAQ,CAAU;IAElB,YAAY,QAAkB;QAC5B,KAAK,CAAC,kBAAkB,QAAQ,EAAE,MAAM,IAAI,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAA;QACnE,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;QAC3B,IAAI,CAAC,MAAM,GAAG,QAAQ,EAAE,MAAM,CAAA;QAC9B,IAAI,CAAC,UAAU,GAAG,QAAQ,EAAE,UAAU,CAAA;QACtC,IAAI,CAAC,MAAM,GAAG,QAAQ,EAAE,MAAM,IAAI,EAAE,CAAA;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAc,EAAE,EAAE;IACnD,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,aAAa,CAAC,KAAiB,CAAC,CAAA;IAC5C,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC9B,CAAC,CAAA","sourcesContent":["import { ApiError } from '../types/api_primitives'\n\nexport class ResponseError extends Error {\n status: number\n statusText: string\n errors: ApiError['errors']\n response: ApiError\n\n constructor(response: ApiError) {\n super(`ResponseError: ${response?.status} ${response?.statusText}`)\n this.name = 'ResponseError'\n this.status = response?.status\n this.statusText = response?.statusText\n this.errors = response?.errors || []\n this.response = response\n }\n}\n\nexport const throwResponseError = (error: unknown) => {\n if (error instanceof Response) {\n throw new ResponseError(error as ApiError)\n }\n\n return Promise.reject(error)\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "3.11.0
|
|
3
|
+
"version": "3.11.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"prettier": "^3.4.2",
|
|
56
56
|
"typescript": "<5.6.0"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "d68607004fe3e05b3e6519564f39953f67c457cb"
|
|
59
59
|
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import React, { useMemo, useState, Dispatch, SetStateAction } from 'react'
|
|
2
2
|
import { StyleSheet, Modal, SafeAreaView, View, Linking, Dimensions } from 'react-native'
|
|
3
3
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Gesture,
|
|
6
|
+
GestureDetector,
|
|
7
|
+
GestureHandlerRootView,
|
|
8
|
+
Pressable,
|
|
9
|
+
} from 'react-native-gesture-handler'
|
|
5
10
|
import {
|
|
6
11
|
runOnJS,
|
|
7
12
|
useAnimatedStyle,
|
|
@@ -509,15 +514,17 @@ const LightboxModal = ({
|
|
|
509
514
|
<SafeAreaView style={styles.modal}>
|
|
510
515
|
<GestureHandlerRootView>
|
|
511
516
|
<GestureDetector gesture={composedGesture}>
|
|
512
|
-
<
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
517
|
+
<PreventPressEventsBubbling>
|
|
518
|
+
<Image
|
|
519
|
+
source={{ uri }}
|
|
520
|
+
loadingBackgroundStyles={styles.lightboxImageLoading}
|
|
521
|
+
style={styles.lightboxImage}
|
|
522
|
+
animatedImageStyle={animatedImageStyles}
|
|
523
|
+
resizeMode="contain"
|
|
524
|
+
animated={true}
|
|
525
|
+
alt=""
|
|
526
|
+
/>
|
|
527
|
+
</PreventPressEventsBubbling>
|
|
521
528
|
</GestureDetector>
|
|
522
529
|
<View style={styles.actionToolbar} accessibilityRole="toolbar">
|
|
523
530
|
<View style={styles.actionToolbarTextMeta}>
|
|
@@ -552,6 +559,14 @@ const LightboxModal = ({
|
|
|
552
559
|
)
|
|
553
560
|
}
|
|
554
561
|
|
|
562
|
+
const PreventPressEventsBubbling = ({ children }: { children: React.ReactNode }) => {
|
|
563
|
+
return (
|
|
564
|
+
<Pressable onLongPress={() => {}} onPress={() => {}}>
|
|
565
|
+
{children}
|
|
566
|
+
</Pressable>
|
|
567
|
+
)
|
|
568
|
+
}
|
|
569
|
+
|
|
555
570
|
interface UseStylesProps {
|
|
556
571
|
imageWidth?: number
|
|
557
572
|
imageHeight?: number
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useNavigation } from '@react-navigation/native'
|
|
2
|
-
import React from 'react'
|
|
2
|
+
import React, { useEffect } from 'react'
|
|
3
3
|
import { Platform, Pressable, StyleSheet, useWindowDimensions, View } from 'react-native'
|
|
4
4
|
import { MessageReaction } from '../../components/conversation/message_reaction'
|
|
5
|
-
import { Avatar, Text } from '../../components/display'
|
|
5
|
+
import { Avatar, Icon, Spinner, Text, TextInlineButton } from '../../components/display'
|
|
6
6
|
import { useInteractionGhostBackgroundColor, useTheme } from '../../hooks'
|
|
7
7
|
import { MessageResource } from '../../types'
|
|
8
8
|
import { ReactionCountResource } from '../../types/resources/reaction'
|
|
@@ -23,6 +23,7 @@ import Animated, {
|
|
|
23
23
|
} from 'react-native-reanimated'
|
|
24
24
|
import { useLiveRelativeTime } from '../../hooks/use_live_relative_time'
|
|
25
25
|
import { MessageReadReceipts } from './message_read_receipts'
|
|
26
|
+
import { isNewMessage, useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update'
|
|
26
27
|
|
|
27
28
|
/** Message
|
|
28
29
|
* Component for display of a message within a conversation list
|
|
@@ -33,16 +34,48 @@ interface MessageProps extends MessageResource {
|
|
|
33
34
|
latestReadMessageSortKey?: string
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
export function Message(
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
export function Message({
|
|
38
|
+
canDeleteNonAuthoredMessages,
|
|
39
|
+
conversation_id,
|
|
40
|
+
latestReadMessageSortKey,
|
|
41
|
+
...message
|
|
42
|
+
}: MessageProps) {
|
|
43
|
+
const { text, reactionCounts, pending, error } = message
|
|
44
|
+
const styles = useMessageStyles(message)
|
|
39
45
|
const navigation = useNavigation()
|
|
40
46
|
const { colors } = useTheme()
|
|
41
47
|
const hasReactions = reactionCounts.length > 0
|
|
42
48
|
const [showMessageMetaToggle, setShowMessageMetaToggle] = React.useState(false)
|
|
43
|
-
const showMessageMeta =
|
|
44
|
-
|
|
45
|
-
const
|
|
49
|
+
const showMessageMeta =
|
|
50
|
+
showMessageMetaToggle || message.myLatestInConversation || !!pending || !!error || false
|
|
51
|
+
const timestamp = useLiveRelativeTime(message.createdAt)
|
|
52
|
+
const wasEdited = Boolean(message.textEditedAt)
|
|
53
|
+
const isPersisted = !isNewMessage(message)
|
|
54
|
+
const [temporarilyHidePendingState, setTemporarilyHidePendingState] = React.useState(true)
|
|
55
|
+
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (pending) {
|
|
58
|
+
const timer = setTimeout(() => {
|
|
59
|
+
setTemporarilyHidePendingState(false)
|
|
60
|
+
}, 2000)
|
|
61
|
+
return () => clearTimeout(timer)
|
|
62
|
+
}
|
|
63
|
+
return () => {}
|
|
64
|
+
}, [pending])
|
|
65
|
+
|
|
66
|
+
const retryFailedSaveMutation = useMessageCreateOrUpdate({
|
|
67
|
+
conversationId: conversation_id,
|
|
68
|
+
message,
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
const handleRetry = () => {
|
|
72
|
+
if (text && error) {
|
|
73
|
+
retryFailedSaveMutation.mutateAsync({
|
|
74
|
+
text,
|
|
75
|
+
attachments: message.attachmentsForCreate,
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
}
|
|
46
79
|
|
|
47
80
|
const bgFadeProgress = useSharedValue(0)
|
|
48
81
|
const pressedColor = Platform.select({
|
|
@@ -69,15 +102,17 @@ export function Message(props: MessageProps) {
|
|
|
69
102
|
}
|
|
70
103
|
|
|
71
104
|
const handleMessageLongPress = () => {
|
|
105
|
+
if (!isPersisted) return
|
|
106
|
+
|
|
72
107
|
navigation.navigate('MessageActions', {
|
|
73
|
-
message_id:
|
|
108
|
+
message_id: message.id,
|
|
74
109
|
conversation_id,
|
|
75
110
|
canDeleteNonAuthoredMessages,
|
|
76
111
|
})
|
|
77
112
|
}
|
|
78
113
|
const handleReactionLongPress = (reaction: ReactionCountResource) => {
|
|
79
114
|
navigation.navigate('Reactions', {
|
|
80
|
-
message_id:
|
|
115
|
+
message_id: message.id,
|
|
81
116
|
conversation_id,
|
|
82
117
|
reaction_value: reaction.value,
|
|
83
118
|
})
|
|
@@ -90,17 +125,18 @@ export function Message(props: MessageProps) {
|
|
|
90
125
|
attachmentUrl: attachment?.attributes.url,
|
|
91
126
|
conversation_id,
|
|
92
127
|
canDeleteNonAuthoredMessages,
|
|
93
|
-
myMessage:
|
|
128
|
+
myMessage: message.mine,
|
|
94
129
|
})
|
|
95
130
|
}
|
|
96
131
|
|
|
97
132
|
const metaProps = {
|
|
98
|
-
authorName:
|
|
99
|
-
createdAt:
|
|
133
|
+
authorName: message.author.name,
|
|
134
|
+
createdAt: message.createdAt,
|
|
100
135
|
}
|
|
101
136
|
|
|
102
|
-
const renderAuthor = (!
|
|
103
|
-
const messageBottomMargin =
|
|
137
|
+
const renderAuthor = (!message.mine && message.renderAuthor) || false
|
|
138
|
+
const messageBottomMargin = message.lastInGroup ? 12 : hasReactions || showMessageMeta ? 8 : 4
|
|
139
|
+
const messagePendingLabel = isPersisted ? 'Saving' : 'Sending'
|
|
104
140
|
|
|
105
141
|
return (
|
|
106
142
|
<Pressable
|
|
@@ -112,21 +148,21 @@ export function Message(props: MessageProps) {
|
|
|
112
148
|
accessibilityHint="Long press to view message actions like reacting and copying."
|
|
113
149
|
>
|
|
114
150
|
<Animated.View style={[styles.message, animatedBackgroundColor]}>
|
|
115
|
-
{!
|
|
151
|
+
{!message.mine && (
|
|
116
152
|
<View style={styles.messageAuthor}>
|
|
117
153
|
{renderAuthor ? (
|
|
118
|
-
<Avatar size={'md'} sourceUri={
|
|
154
|
+
<Avatar size={'md'} sourceUri={message.author.avatar} />
|
|
119
155
|
) : (
|
|
120
156
|
<View style={styles.avatarPlaceholder} />
|
|
121
157
|
)}
|
|
122
158
|
</View>
|
|
123
159
|
)}
|
|
124
160
|
<View style={[styles.messageContent, { marginBottom: messageBottomMargin }]}>
|
|
125
|
-
{renderAuthor && <Text variant="tertiary">{
|
|
161
|
+
{renderAuthor && <Text variant="tertiary">{message.author.name}</Text>}
|
|
126
162
|
<View style={styles.messageBubble}>
|
|
127
163
|
<ErrorBoundary>
|
|
128
164
|
<MessageAttachments
|
|
129
|
-
attachments={
|
|
165
|
+
attachments={message.attachments}
|
|
130
166
|
metaProps={metaProps}
|
|
131
167
|
onMessageAttachmentLongPress={handleMessageAttachmentLongPress}
|
|
132
168
|
onMessageLongPress={handleMessageLongPress}
|
|
@@ -145,7 +181,7 @@ export function Message(props: MessageProps) {
|
|
|
145
181
|
key={reaction.value}
|
|
146
182
|
reaction={reaction}
|
|
147
183
|
onLongPress={handleReactionLongPress}
|
|
148
|
-
message={
|
|
184
|
+
message={message}
|
|
149
185
|
conversationId={conversation_id}
|
|
150
186
|
/>
|
|
151
187
|
))}
|
|
@@ -153,14 +189,44 @@ export function Message(props: MessageProps) {
|
|
|
153
189
|
)}
|
|
154
190
|
{showMessageMeta && (
|
|
155
191
|
<View style={styles.messageMeta}>
|
|
156
|
-
{
|
|
192
|
+
{message.mine && !pending && !error && (
|
|
157
193
|
<MessageReadReceipts
|
|
158
|
-
message={
|
|
159
|
-
latestReadMessageSortKey={
|
|
194
|
+
message={message}
|
|
195
|
+
latestReadMessageSortKey={latestReadMessageSortKey}
|
|
160
196
|
/>
|
|
161
197
|
)}
|
|
162
|
-
|
|
163
|
-
|
|
198
|
+
{error ? (
|
|
199
|
+
<View style={styles.errorContainer}>
|
|
200
|
+
{retryFailedSaveMutation.isPending ? (
|
|
201
|
+
<Spinner size={12} style={styles.errorSpinner} />
|
|
202
|
+
) : (
|
|
203
|
+
<Icon name="general.exclamationTriangle" size={12} style={styles.errorIcon} />
|
|
204
|
+
)}
|
|
205
|
+
<Text variant="footnote" style={styles.errorText}>
|
|
206
|
+
Failed to {isPersisted ? 'edit' : 'send'} |{' '}
|
|
207
|
+
<TextInlineButton
|
|
208
|
+
onPress={handleRetry}
|
|
209
|
+
variant="footnote"
|
|
210
|
+
appearance="danger"
|
|
211
|
+
disabled={retryFailedSaveMutation.isPending}
|
|
212
|
+
>
|
|
213
|
+
Try again
|
|
214
|
+
</TextInlineButton>
|
|
215
|
+
</Text>
|
|
216
|
+
</View>
|
|
217
|
+
) : pending && (!temporarilyHidePendingState || isPersisted) ? (
|
|
218
|
+
<View style={styles.pendingIndicatorContainer}>
|
|
219
|
+
<Icon
|
|
220
|
+
name="general.outlinedClock"
|
|
221
|
+
size={12}
|
|
222
|
+
color={colors.iconColorDefaultSecondary}
|
|
223
|
+
/>
|
|
224
|
+
<Text variant="footnote">{messagePendingLabel}</Text>
|
|
225
|
+
</View>
|
|
226
|
+
) : isPersisted ? (
|
|
227
|
+
<Text variant="footnote">{timestamp}</Text>
|
|
228
|
+
) : null}
|
|
229
|
+
{!pending && !error && wasEdited && (
|
|
164
230
|
<Text variant="footnote">
|
|
165
231
|
|{' '}
|
|
166
232
|
<Text variant="footnote" style={styles.editedText}>
|
|
@@ -176,13 +242,14 @@ export function Message(props: MessageProps) {
|
|
|
176
242
|
)
|
|
177
243
|
}
|
|
178
244
|
|
|
179
|
-
const useMessageStyles = (
|
|
180
|
-
const { mine } = props
|
|
245
|
+
const useMessageStyles = ({ mine }: MessageResource) => {
|
|
181
246
|
const { colors } = useTheme()
|
|
182
247
|
const myMessageBackgroundColor = useInteractionGhostBackgroundColor()
|
|
183
248
|
const { width } = useWindowDimensions()
|
|
184
249
|
const tabletWidth = width >= 744 // Smallest iPad Mini's width
|
|
185
250
|
|
|
251
|
+
const messageBubbleBackgroundColor = mine ? myMessageBackgroundColor : colors.fillColorNeutral070
|
|
252
|
+
|
|
186
253
|
return StyleSheet.create({
|
|
187
254
|
message: {
|
|
188
255
|
gap: 8,
|
|
@@ -202,7 +269,7 @@ const useMessageStyles = (props: MessageResource) => {
|
|
|
202
269
|
height: 32, // Same height as avatar
|
|
203
270
|
},
|
|
204
271
|
messageBubble: {
|
|
205
|
-
backgroundColor:
|
|
272
|
+
backgroundColor: messageBubbleBackgroundColor,
|
|
206
273
|
borderRadius: 8,
|
|
207
274
|
maxWidth: tabletWidth ? 360 : '80%',
|
|
208
275
|
alignSelf: mine ? 'flex-end' : 'flex-start',
|
|
@@ -225,5 +292,26 @@ const useMessageStyles = (props: MessageResource) => {
|
|
|
225
292
|
editedText: {
|
|
226
293
|
fontWeight: platformFontWeightMedium,
|
|
227
294
|
},
|
|
295
|
+
pendingIndicatorContainer: {
|
|
296
|
+
flexDirection: 'row',
|
|
297
|
+
alignItems: 'center',
|
|
298
|
+
gap: 4,
|
|
299
|
+
},
|
|
300
|
+
errorContainer: {
|
|
301
|
+
flexDirection: 'row',
|
|
302
|
+
alignItems: 'center',
|
|
303
|
+
gap: 4,
|
|
304
|
+
},
|
|
305
|
+
errorIcon: {
|
|
306
|
+
color: colors.statusErrorIcon,
|
|
307
|
+
},
|
|
308
|
+
errorText: {
|
|
309
|
+
color: colors.statusErrorText,
|
|
310
|
+
},
|
|
311
|
+
errorSpinner: {
|
|
312
|
+
position: 'relative',
|
|
313
|
+
width: 'auto',
|
|
314
|
+
height: 'auto',
|
|
315
|
+
},
|
|
228
316
|
})
|
|
229
317
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { FileAttachment } from '../../../hooks/use_attachment_uploader'
|
|
3
2
|
import { ImageAttachmentPreview } from '../../display'
|
|
3
|
+
import { FileAttachment } from '../../../types/resources/denormalized_attachment_resource_for_create'
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
6
|
uri: string
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { FileAttachment } from '../../../hooks/use_attachment_uploader'
|
|
3
2
|
import { VideoAttachmentPreview } from '../../display'
|
|
3
|
+
import { FileAttachment } from '../../../types/resources/denormalized_attachment_resource_for_create'
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
6
|
status: FileAttachment['status']
|
|
@@ -32,7 +32,7 @@ import { useAttachmentUploader } from '../../hooks/use_attachment_uploader'
|
|
|
32
32
|
import {
|
|
33
33
|
DenormalizedAttachmentResourceForCreate,
|
|
34
34
|
DenormalizedMessageAttachmentResourceForCreate,
|
|
35
|
-
} from '../../types/resources/
|
|
35
|
+
} from '../../types/resources/denormalized_attachment_resource_for_create'
|
|
36
36
|
import { MessageFormAttachmentImage } from './message_form/message_form_attachment_image'
|
|
37
37
|
import { useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update'
|
|
38
38
|
import { useBroadcastTypingStatus } from '../../hooks/use_broadcast_typing_status'
|
|
@@ -99,7 +99,7 @@ function MessageFormRoot({
|
|
|
99
99
|
mutateAsync,
|
|
100
100
|
} = useMessageCreateOrUpdate({
|
|
101
101
|
conversationId: conversation.id,
|
|
102
|
-
|
|
102
|
+
message: currentlyEditingMessage || undefined,
|
|
103
103
|
})
|
|
104
104
|
const attachmentUploader = useAttachmentUploader({
|
|
105
105
|
conversationId: conversation.id,
|
|
@@ -175,19 +175,22 @@ function MessageFormRoot({
|
|
|
175
175
|
TextInput.State.blurTextInput(TextInput.State.currentlyFocusedInput())
|
|
176
176
|
navigateToSendGiphyAfterKeyboardHides()
|
|
177
177
|
} else {
|
|
178
|
-
let attachmentsForSubmit: DenormalizedAttachmentResourceForCreate[] =
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
178
|
+
let attachmentsForSubmit: DenormalizedAttachmentResourceForCreate[] =
|
|
179
|
+
attachmentUploader.attachments
|
|
180
|
+
.filter(a => a.status === 'success' && a.id)
|
|
181
|
+
.map(
|
|
182
|
+
(attachment): DenormalizedMessageAttachmentResourceForCreate => ({
|
|
183
|
+
type: 'MessageAttachment',
|
|
184
|
+
id: attachment.id as string,
|
|
185
|
+
file: attachment.file,
|
|
186
|
+
})
|
|
187
|
+
)
|
|
187
188
|
if (currentlyEditingMessage) {
|
|
188
|
-
mutateAsync({ text })
|
|
189
|
+
mutateAsync({ text })
|
|
190
|
+
reset()
|
|
189
191
|
} else {
|
|
190
|
-
mutateAsync({ text, attachments: attachmentsForSubmit })
|
|
192
|
+
mutateAsync({ text, attachments: attachmentsForSubmit })
|
|
193
|
+
reset()
|
|
191
194
|
}
|
|
192
195
|
}
|
|
193
196
|
}
|
|
@@ -4,9 +4,10 @@ import React, { useMemo } from 'react'
|
|
|
4
4
|
import { StyleSheet, View } from 'react-native'
|
|
5
5
|
import { useConversationsContext } from '../../contexts/conversations_context'
|
|
6
6
|
import { useTheme } from '../../hooks'
|
|
7
|
+
import { ConversationResource } from '../../types'
|
|
8
|
+
import { throwResponseError } from '../../utils/response_error'
|
|
7
9
|
import { BlankState } from '../display'
|
|
8
10
|
import { ConversationPreview, ConversationPreviewSkeleton } from './conversation_preview'
|
|
9
|
-
import { ConversationResource } from '../../types'
|
|
10
11
|
|
|
11
12
|
interface ConversationsProps {
|
|
12
13
|
ListHeaderComponent?:
|
|
@@ -26,6 +27,8 @@ export const Conversations = ({ ListHeaderComponent }: ConversationsProps) => {
|
|
|
26
27
|
refetch,
|
|
27
28
|
isRefetching,
|
|
28
29
|
isFetched,
|
|
30
|
+
isError,
|
|
31
|
+
error,
|
|
29
32
|
args: { chat_group_graph_id },
|
|
30
33
|
} = useConversationsContext()
|
|
31
34
|
const navigation = useNavigation()
|
|
@@ -43,6 +46,10 @@ export const Conversations = ({ ListHeaderComponent }: ConversationsProps) => {
|
|
|
43
46
|
}))
|
|
44
47
|
}, [conversations, isLoading])
|
|
45
48
|
|
|
49
|
+
if (isError) {
|
|
50
|
+
throwResponseError(error)
|
|
51
|
+
}
|
|
52
|
+
|
|
46
53
|
return (
|
|
47
54
|
<View style={styles.container}>
|
|
48
55
|
<FlashList
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react'
|
|
2
|
-
import { Animated, Easing, StyleSheet, View } from 'react-native'
|
|
2
|
+
import { Animated, Easing, StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
|
|
3
3
|
import { useFontScale, useTheme } from '../../hooks'
|
|
4
4
|
|
|
5
5
|
// =================================
|
|
@@ -21,11 +21,16 @@ interface SpinnerProps {
|
|
|
21
21
|
* Specifies the maximum size spinner can scale to if the device's font-size is increased.
|
|
22
22
|
*/
|
|
23
23
|
maxFontSizeMultiplier?: number
|
|
24
|
+
/**
|
|
25
|
+
* Style to apply to the spinner
|
|
26
|
+
*/
|
|
27
|
+
style?: StyleProp<ViewStyle>
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
export function Spinner({
|
|
27
31
|
size = 20,
|
|
28
32
|
maxFontSizeMultiplier = PREVENT_SCALING_DEFAULT,
|
|
33
|
+
style,
|
|
29
34
|
}: SpinnerProps) {
|
|
30
35
|
const rotation = useRef(new Animated.Value(0)).current
|
|
31
36
|
|
|
@@ -53,7 +58,7 @@ export function Spinner({
|
|
|
53
58
|
useEffect(() => () => rotation.setValue(0), [rotation])
|
|
54
59
|
|
|
55
60
|
return (
|
|
56
|
-
<View style={styles.container}>
|
|
61
|
+
<View style={[styles.container, style]}>
|
|
57
62
|
<Animated.View style={styles.animatedContainer}>
|
|
58
63
|
<View style={styles.clipping}>
|
|
59
64
|
<View style={[styles.circle, styles.spinner]} />
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useTheme } from '../../hooks'
|
|
2
2
|
import React from 'react'
|
|
3
|
-
import { StyleSheet, Text as ReactNativeText } from 'react-native'
|
|
3
|
+
import { StyleSheet, Text as ReactNativeText, Platform } from 'react-native'
|
|
4
4
|
import type { TextStyle, TextProps as ReactNativeTextProps } from 'react-native'
|
|
5
5
|
import { tokens } from '../../vendor/tapestry/tokens'
|
|
6
6
|
|
|
@@ -39,7 +39,7 @@ export function Text({ style, variant = 'plain', children, ...props }: TextProps
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
return (
|
|
42
|
-
<ReactNativeText style={[variantStyleMap[variant], style]} {...props}>
|
|
42
|
+
<ReactNativeText style={[styles.base, variantStyleMap[variant], style]} {...props}>
|
|
43
43
|
{children}
|
|
44
44
|
</ReactNativeText>
|
|
45
45
|
)
|
|
@@ -52,6 +52,14 @@ export function Text({ style, variant = 'plain', children, ...props }: TextProps
|
|
|
52
52
|
const useStyles = () => {
|
|
53
53
|
const { colors } = useTheme()
|
|
54
54
|
return StyleSheet.create({
|
|
55
|
+
base: {
|
|
56
|
+
...Platform.select({
|
|
57
|
+
android: {
|
|
58
|
+
fontFamily: 'normal', // This forces the text to be normal weight when the "Bold font" accessibility setting is enabled. While this is not ideal, it fixes a bug where the text without a hard coded fontWeight gets cut off on Android. https://github.com/facebook/react-native/issues/15114
|
|
59
|
+
},
|
|
60
|
+
default: null, // iOS needs to specify its own font family otherwise the italic style won't work. (Used in message_markdown.tsx) It's "Bold font" accessibility setting works as expected.
|
|
61
|
+
}),
|
|
62
|
+
},
|
|
55
63
|
plain: {
|
|
56
64
|
color: colors.textColorDefaultPrimary,
|
|
57
65
|
fontSize: tokens.fontSizeMd,
|
|
@@ -113,13 +113,14 @@ function AndroidSheetGrabber() {
|
|
|
113
113
|
|
|
114
114
|
interface FormSheetHeaderProps {
|
|
115
115
|
children: ReactNode
|
|
116
|
+
style?: StyleProp<ViewStyle>
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
function FormSheetHeader({ children }: FormSheetHeaderProps) {
|
|
119
|
+
function FormSheetHeader({ children, style }: FormSheetHeaderProps) {
|
|
119
120
|
const styles = useStyles()
|
|
120
121
|
|
|
121
122
|
return (
|
|
122
|
-
<View style={styles.header}>
|
|
123
|
+
<View style={[styles.header, style]}>
|
|
123
124
|
<View style={styles.headerContent}>{children}</View>
|
|
124
125
|
</View>
|
|
125
126
|
)
|