@planningcenter/chat-react-native 3.7.0-rc.4 → 3.7.0-rc.6
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/audio_attachment.d.ts.map +1 -1
- package/build/components/conversation/attachments/audio_attachment.js +2 -0
- package/build/components/conversation/attachments/audio_attachment.js.map +1 -1
- package/build/components/conversation/message_form.d.ts.map +1 -1
- package/build/components/conversation/message_form.js +72 -21
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/components/page/error_boundary.d.ts +1 -1
- package/build/utils/native_adapters/audio.d.ts +1 -0
- package/build/utils/native_adapters/audio.d.ts.map +1 -1
- package/build/utils/native_adapters/audio.js.map +1 -1
- package/package.json +2 -2
- package/src/components/conversation/attachments/audio_attachment.tsx +2 -0
- package/src/components/conversation/message_form.tsx +95 -27
- package/src/utils/native_adapters/audio.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio_attachment.d.ts","sourceRoot":"","sources":["../../../../src/components/conversation/attachments/audio_attachment.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,qCAAqC,EAAE,MAAM,2DAA2D,CAAA;AAOjH,wBAAgB,eAAe,CAAC,EAC9B,UAAU,EACV,4BAA4B,GAC7B,EAAE;IACD,UAAU,EAAE,qCAAqC,CAAA;IACjD,4BAA4B,EAAE,CAAC,UAAU,EAAE,qCAAqC,KAAK,IAAI,CAAA;CAC1F,
|
|
1
|
+
{"version":3,"file":"audio_attachment.d.ts","sourceRoot":"","sources":["../../../../src/components/conversation/attachments/audio_attachment.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,qCAAqC,EAAE,MAAM,2DAA2D,CAAA;AAOjH,wBAAgB,eAAe,CAAC,EAC9B,UAAU,EACV,4BAA4B,GAC7B,EAAE;IACD,UAAU,EAAE,qCAAqC,CAAA;IACjD,4BAA4B,EAAE,CAAC,UAAU,EAAE,qCAAqC,KAAK,IAAI,CAAA;CAC1F,qBAsDA"}
|
|
@@ -11,6 +11,7 @@ export function AudioAttachment({ attachment, onMessageAttachmentLongPress, }) {
|
|
|
11
11
|
const { attributes } = attachment;
|
|
12
12
|
const { url, filename } = attributes;
|
|
13
13
|
const sound = Audio.useAudio(url);
|
|
14
|
+
const { AudioPlayer } = sound;
|
|
14
15
|
function toggleAudio() {
|
|
15
16
|
if (!sound.isPlaying) {
|
|
16
17
|
sound.play();
|
|
@@ -23,6 +24,7 @@ export function AudioAttachment({ attachment, onMessageAttachmentLongPress, }) {
|
|
|
23
24
|
return (<PlatformPressable onLongPress={() => onMessageAttachmentLongPress(attachment)} android_ripple={{ color: colors.androidRippleNeutral, foreground: true }} accessibilityHint="Long press for more options">
|
|
24
25
|
<AttachmentCard>
|
|
25
26
|
<View style={styles.container}>
|
|
27
|
+
{AudioPlayer}
|
|
26
28
|
<IconButton name={sound.isPlaying ? 'services.pause' : 'services.play'} size="md" accessibilityLabel={sound.isPlaying ? 'Pause' : 'Play'} onPress={toggleAudio} disabled={!sound} style={styles.button} iconStyle={styles.buttonIcon}/>
|
|
27
29
|
<View style={styles.details}>
|
|
28
30
|
<AttachmentCardTitle>{filename}</AttachmentCardTitle>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio_attachment.js","sourceRoot":"","sources":["../../../../src/components/conversation/attachments/audio_attachment.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAA;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAE9D,MAAM,UAAU,eAAe,CAAC,EAC9B,UAAU,EACV,4BAA4B,GAI7B;IACC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAE7B,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,CAAA;IACjC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAA;IACpC,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"audio_attachment.js","sourceRoot":"","sources":["../../../../src/components/conversation/attachments/audio_attachment.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react'\nimport { View, StyleSheet } from 'react-native'\nimport { DenormalizedMessageAttachmentResource } from '../../../types/resources/denormalized_attachment_resource'\nimport { IconButton, Text } from '../../display'\nimport { AttachmentCard, AttachmentCardTitle } from './attachment_card'\nimport { useTheme } from '../../../hooks'\nimport { Audio } from '../../../utils/native_adapters'\nimport { PlatformPressable } from '@react-navigation/elements'\n\nexport function AudioAttachment({\n attachment,\n onMessageAttachmentLongPress,\n}: {\n attachment: DenormalizedMessageAttachmentResource\n onMessageAttachmentLongPress: (attachment: DenormalizedMessageAttachmentResource) => void\n}) {\n const styles = useStyles()\n const { colors } = useTheme()\n\n const { attributes } = attachment\n const { url, filename } = attributes\n const sound = Audio.useAudio(url)\n const { AudioPlayer } = sound\n\n function toggleAudio() {\n if (!sound.isPlaying) {\n sound.play()\n } else {\n sound.pause()\n }\n }\n\n const progress = sound.duration > 0 ? sound.position / sound.duration : 0\n\n return (\n <PlatformPressable\n onLongPress={() => onMessageAttachmentLongPress(attachment)}\n android_ripple={{ color: colors.androidRippleNeutral, foreground: true }}\n accessibilityHint=\"Long press for more options\"\n >\n <AttachmentCard>\n <View style={styles.container}>\n {AudioPlayer}\n <IconButton\n name={sound.isPlaying ? 'services.pause' : 'services.play'}\n size=\"md\"\n accessibilityLabel={sound.isPlaying ? 'Pause' : 'Play'}\n onPress={toggleAudio}\n disabled={!sound}\n style={styles.button}\n iconStyle={styles.buttonIcon}\n />\n <View style={styles.details}>\n <AttachmentCardTitle>{filename}</AttachmentCardTitle>\n <View style={styles.progressContainer}>\n <View style={styles.progressTrack}>\n <View style={[styles.progressBar, { width: `${progress * 100}%` }]} />\n </View>\n </View>\n {sound.isPlaying ? (\n <ProgressionText progress={sound.position || 0} />\n ) : (\n <DurationText duration={sound.duration || 0} />\n )}\n </View>\n </View>\n </AttachmentCard>\n </PlatformPressable>\n )\n}\n\nconst DurationText = ({ duration }: { duration: number }) => {\n if (duration === 0) return <Text variant=\"footnote\">Loading...</Text>\n\n const { minutes, seconds } = getMinutesAndSeconds(duration)\n const secondsLabel = `${seconds}s`\n const minutesLabel = `${minutes}m`\n const label = minutes > 0 ? `${minutesLabel} ${secondsLabel}` : secondsLabel\n\n return <Text variant=\"footnote\">{label}</Text>\n}\n\nconst ProgressionText = ({ progress }: { progress: number }) => {\n if (progress === 0) return <Text variant=\"footnote\">Loading...</Text>\n\n const { minutes, seconds } = getMinutesAndSeconds(progress)\n const twoDigitSeconds = seconds.toString().padStart(2, '0')\n const twoDigitMinutes = minutes.toString().padStart(2, '0')\n\n return <Text variant=\"footnote\">{`${twoDigitMinutes}:${twoDigitSeconds}`}</Text>\n}\n\nfunction getMinutesAndSeconds(ms?: number) {\n if (!ms || ms === 0) return { minutes: 0, seconds: 0 }\n\n const totalSeconds = Math.floor(ms / 1000)\n const minutes = Math.floor(totalSeconds / 60)\n const seconds = totalSeconds % 60\n\n return { minutes, seconds }\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n\n return StyleSheet.create({\n container: {\n flexDirection: 'row',\n alignItems: 'center',\n },\n button: {\n width: 42,\n height: 42,\n justifyContent: 'center',\n alignItems: 'center',\n borderRadius: 25,\n backgroundColor: colors.fillColorNeutral100Inverted,\n borderColor: colors.borderColorDefaultBase,\n borderWidth: 1,\n },\n buttonIcon: {\n color: colors.iconColorDefaultPrimary,\n },\n buttonText: {\n fontSize: 32,\n lineHeight: 32,\n },\n details: {\n flex: 1,\n marginLeft: 10,\n gap: 4,\n },\n progressContainer: {\n marginTop: 2,\n },\n progressTrack: {\n height: 4,\n backgroundColor: colors.borderColorDefaultBase,\n borderRadius: 2,\n overflow: 'hidden',\n },\n progressBar: {\n height: '100%',\n borderRadius: 2,\n backgroundColor: colors.interaction,\n },\n })\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message_form.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/message_form.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAuD,MAAM,OAAO,CAAA;AAC3E,OAAO,
|
|
1
|
+
{"version":3,"file":"message_form.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/message_form.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAuD,MAAM,OAAO,CAAA;AAC3E,OAAO,EAAoD,SAAS,EAAE,MAAM,cAAc,CAAA;AAG1F,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAkBnE,eAAO,MAAM,WAAW;;;;;;CAOvB,CAAA;AAED,UAAU,qBAAsB,SAAQ,SAAS;IAC/C,YAAY,EAAE,oBAAoB,CAAA;IAClC,uBAAuB,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;CACjD;AA0BD,iBAAS,eAAe,CAAC,EACvB,YAAY,EACZ,uBAAuB,EACvB,QAAQ,GACT,EAAE,qBAAqB,qBAoHvB;AAiCD,iBAAS,gBAAgB,sBA6CxB;AAED,iBAAS,oBAAoB,sBA8C5B;AAED,iBAAS,2BAA2B,6BAoFnC;AAED,iBAAS,mBAAmB,6BAgC3B"}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { useNavigation, useTheme as useNavigationTheme, useRoute, } from '@react-navigation/native';
|
|
2
2
|
import React, { useCallback, useContext, useEffect, useState } from 'react';
|
|
3
|
-
import { StyleSheet, TextInput, View } from 'react-native';
|
|
4
|
-
import { IconButton, Text } from '../../components';
|
|
5
|
-
import { useTheme } from '../../hooks';
|
|
3
|
+
import { Platform, Pressable, StyleSheet, TextInput, View } from 'react-native';
|
|
4
|
+
import { Icon, IconButton, Text } from '../../components';
|
|
5
|
+
import { useCreateAndroidRippleColor, useTheme } from '../../hooks';
|
|
6
6
|
import { ChatContext } from '../../contexts/chat_context';
|
|
7
7
|
import { ImagePicker } from '../../utils/native_adapters';
|
|
8
|
+
import { platformPressedOpacityStyle } from '../../utils';
|
|
8
9
|
import { useAttachmentUploader } from '../../hooks/use_attachment_uploader';
|
|
9
10
|
import { MessageFormAttachmentImage } from './message_form/message_form_attachment_image';
|
|
10
11
|
import { useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update';
|
|
11
12
|
import { useBroadcastTypingStatus } from '../../hooks/use_broadcast_typing_status';
|
|
13
|
+
import { tokens } from '../../vendor/tapestry/tokens';
|
|
14
|
+
import LinearGradient from 'react-native-linear-gradient';
|
|
12
15
|
export const MessageForm = {
|
|
13
16
|
Root: MessageFormRoot,
|
|
14
17
|
TextInput: MessageFormInput,
|
|
@@ -150,6 +153,7 @@ function MessageFormAttachments() {
|
|
|
150
153
|
}
|
|
151
154
|
function MessageFormInput() {
|
|
152
155
|
const styles = useMessageFormStyles();
|
|
156
|
+
const theme = useTheme();
|
|
153
157
|
const { text, setText, onSubmit, usingGiphy, attachmentUploader } = React.useContext(MessageFormContext);
|
|
154
158
|
const attachmentError = attachmentUploader?.errorMessage;
|
|
155
159
|
const route = useRoute();
|
|
@@ -168,16 +172,37 @@ function MessageFormInput() {
|
|
|
168
172
|
<Text style={styles.giphyBadgeText}>/giphy</Text>
|
|
169
173
|
</View>) : null}
|
|
170
174
|
|
|
171
|
-
<TextInput style={[styles.textInput, usingGiphy && styles.textInputWithGiphy]} multiline={true} aria-disabled={true} placeholder="Send a message" onChangeText={handleTextChange} value={text} maxLength={usingGiphy ? GIPHY_MAX_LENGTH : MAX_MESSAGE_LENGTH} onSubmitEditing={onSubmit}/>
|
|
175
|
+
<TextInput style={[styles.textInput, usingGiphy && styles.textInputWithGiphy]} multiline={true} aria-disabled={true} placeholder="Send a message" placeholderTextColor={theme.colors.textColorDefaultPlaceholder} onChangeText={handleTextChange} value={text} maxLength={usingGiphy ? GIPHY_MAX_LENGTH : MAX_MESSAGE_LENGTH} onSubmitEditing={onSubmit}/>
|
|
172
176
|
</View>
|
|
173
177
|
|
|
174
178
|
{attachmentError ? <Text style={styles.inputErrorMessage}>{attachmentError}</Text> : null}
|
|
175
179
|
</View>);
|
|
176
180
|
}
|
|
177
181
|
function MessageFormSubmitBtn() {
|
|
178
|
-
const styles = useMessageFormStyles();
|
|
179
182
|
const { onSubmit, disabled, usingGiphy } = React.useContext(MessageFormContext);
|
|
180
|
-
|
|
183
|
+
const styles = useMessageFormStyles();
|
|
184
|
+
const { colors } = useTheme();
|
|
185
|
+
const colorKey = disabled ? 'disabled' : 'interaction';
|
|
186
|
+
const interactionStart = colors.buttonStart || colors.interaction;
|
|
187
|
+
const interactionEnd = colors.buttonEnd || colors.interaction;
|
|
188
|
+
const colorMap = {
|
|
189
|
+
disabled: [
|
|
190
|
+
colors.fillColorButtonNeutralSolidDisabled,
|
|
191
|
+
colors.fillColorButtonNeutralSolidDisabled,
|
|
192
|
+
],
|
|
193
|
+
interaction: [interactionStart, interactionEnd],
|
|
194
|
+
};
|
|
195
|
+
const androidRippleColor = useCreateAndroidRippleColor({ color: colorMap[colorKey][0] });
|
|
196
|
+
const gradientColors = colorMap[colorKey];
|
|
197
|
+
const iconStyles = [styles.submitIcon, disabled && styles.submitIconDisabled];
|
|
198
|
+
return (<Pressable disabled={disabled} onPress={onSubmit} accessibilityRole="button" accessibilityLabel={usingGiphy ? 'Search Giphy' : 'Send message'} style={({ pressed }) => [
|
|
199
|
+
styles.submitPressableWrapper,
|
|
200
|
+
pressed && platformPressedOpacityStyle,
|
|
201
|
+
]} android_ripple={{ color: androidRippleColor, borderless: false, foreground: true }}>
|
|
202
|
+
<LinearGradient start={{ x: 0.1, y: 0.1 }} end={{ x: 0.9, y: 0.9 }} colors={gradientColors} style={styles.submitGradientWrapper}>
|
|
203
|
+
<Icon name={usingGiphy ? 'general.search' : 'general.upArrow'} style={iconStyles} accessibilityElementsHidden={true}/>
|
|
204
|
+
</LinearGradient>
|
|
205
|
+
</Pressable>);
|
|
181
206
|
}
|
|
182
207
|
function MessageFormAttachmentPicker() {
|
|
183
208
|
const styles = useMessageFormStyles();
|
|
@@ -220,14 +245,12 @@ function MessageFormAttachmentPicker() {
|
|
|
220
245
|
if (usingGiphy || currentlyEditingMessage) {
|
|
221
246
|
return null;
|
|
222
247
|
}
|
|
223
|
-
return (
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
<IconButton accessibilityLabel="Take a photo" size="md" appearance="neutral" name={'general.videoCamera'} onPress={openCamera}/>
|
|
228
|
-
<IconButton accessibilityLabel="Choose a photo" size="md" appearance="neutral" name={'churchCenter.photosIos'} onPress={pickImage}/>
|
|
248
|
+
return (<View style={styles.attachmentPicker}>
|
|
249
|
+
{isOpen && (<View style={styles.attachmentPickerButtonsContainer}>
|
|
250
|
+
<IconButton accessibilityLabel="Take a photo" accessibilityHint="Opens your camera" size="lg" appearance="neutral" name="general.videoCamera" onPress={openCamera} style={styles.attachmentPickerButton}/>
|
|
251
|
+
<IconButton accessibilityLabel="Choose a photo" accessibilityHint="Opens your photo gallery" size="lg" appearance="neutral" name="churchCenter.photosIos" onPress={pickImage} style={styles.attachmentPickerButton}/>
|
|
229
252
|
</View>)}
|
|
230
|
-
<IconButton accessibilityLabel="File Menu" size="
|
|
253
|
+
<IconButton accessibilityLabel="File Menu" accessibilityHint="Opens options to attach or take a photo" size="lg" appearance="neutral" name="general.paperclip" onPress={() => setIsOpen(!isOpen)} style={styles.formButton}/>
|
|
231
254
|
</View>);
|
|
232
255
|
}
|
|
233
256
|
function MessageFormCommands() {
|
|
@@ -239,7 +262,7 @@ function MessageFormCommands() {
|
|
|
239
262
|
if (usingGiphy) {
|
|
240
263
|
return (<IconButton accessibilityLabel="Exit Giphy Search" size="md" appearance="neutral" name={'general.x'} onPress={() => setUsingGiphy(false)} style={styles.formButton}/>);
|
|
241
264
|
}
|
|
242
|
-
return (<IconButton accessibilityLabel="Search Giphy" size="
|
|
265
|
+
return (<IconButton accessibilityLabel="Search Giphy" size="lg" appearance="neutral" name={'general.bolt'} onPress={() => setUsingGiphy(true)} disabled={text.length > GIPHY_MAX_LENGTH} style={styles.formButton}/>);
|
|
243
266
|
}
|
|
244
267
|
function EditingIndicator() {
|
|
245
268
|
const { currentlyEditingMessage } = React.useContext(MessageFormContext);
|
|
@@ -256,7 +279,7 @@ function EditingIndicator() {
|
|
|
256
279
|
const useMessageFormStyles = () => {
|
|
257
280
|
const theme = useTheme();
|
|
258
281
|
const navigationTheme = useNavigationTheme();
|
|
259
|
-
const buttonSize =
|
|
282
|
+
const buttonSize = 38;
|
|
260
283
|
return StyleSheet.create({
|
|
261
284
|
container: {
|
|
262
285
|
borderColor: theme.colors.fillColorNeutral050Base,
|
|
@@ -267,7 +290,7 @@ const useMessageFormStyles = () => {
|
|
|
267
290
|
backgroundColor: navigationTheme.colors.card,
|
|
268
291
|
flexDirection: 'row',
|
|
269
292
|
alignItems: 'flex-end',
|
|
270
|
-
gap:
|
|
293
|
+
gap: 16,
|
|
271
294
|
},
|
|
272
295
|
textInputBoundary: {
|
|
273
296
|
borderRadius: 24,
|
|
@@ -283,7 +306,7 @@ const useMessageFormStyles = () => {
|
|
|
283
306
|
},
|
|
284
307
|
textInput: {
|
|
285
308
|
paddingVertical: 8,
|
|
286
|
-
paddingHorizontal:
|
|
309
|
+
paddingHorizontal: 16,
|
|
287
310
|
color: theme.colors.textColorDefaultPrimary,
|
|
288
311
|
textAlignVertical: 'center',
|
|
289
312
|
justifyContent: 'center',
|
|
@@ -308,20 +331,48 @@ const useMessageFormStyles = () => {
|
|
|
308
331
|
formButton: {
|
|
309
332
|
height: buttonSize,
|
|
310
333
|
},
|
|
311
|
-
|
|
312
|
-
borderRadius:
|
|
334
|
+
submitPressableWrapper: {
|
|
335
|
+
borderRadius: buttonSize,
|
|
336
|
+
overflow: 'hidden',
|
|
337
|
+
},
|
|
338
|
+
submitGradientWrapper: {
|
|
339
|
+
flexDirection: 'row',
|
|
340
|
+
justifyContent: 'center',
|
|
341
|
+
alignItems: 'center',
|
|
342
|
+
borderRadius: buttonSize,
|
|
313
343
|
height: buttonSize,
|
|
314
344
|
width: buttonSize,
|
|
315
345
|
},
|
|
346
|
+
submitIcon: {
|
|
347
|
+
fontSize: 16,
|
|
348
|
+
color: tokens.colorNeutral100White,
|
|
349
|
+
},
|
|
350
|
+
submitIconDisabled: {
|
|
351
|
+
color: theme.colors.iconColorDefaultDisabled,
|
|
352
|
+
},
|
|
316
353
|
attachmentPicker: {
|
|
317
354
|
position: 'relative',
|
|
318
355
|
},
|
|
319
|
-
|
|
356
|
+
attachmentPickerButtonsContainer: {
|
|
320
357
|
position: 'absolute',
|
|
321
358
|
left: 0,
|
|
322
359
|
bottom: 40,
|
|
323
360
|
zIndex: 10,
|
|
324
|
-
gap:
|
|
361
|
+
gap: 12,
|
|
362
|
+
},
|
|
363
|
+
attachmentPickerButton: {
|
|
364
|
+
backgroundColor: theme.colors.fillColorNeutral070,
|
|
365
|
+
borderRadius: 20,
|
|
366
|
+
height: buttonSize,
|
|
367
|
+
width: buttonSize,
|
|
368
|
+
elevation: 3,
|
|
369
|
+
...Platform.select({
|
|
370
|
+
ios: {
|
|
371
|
+
borderWidth: 1,
|
|
372
|
+
borderColor: theme.colors.borderColorDefaultBase,
|
|
373
|
+
},
|
|
374
|
+
default: null,
|
|
375
|
+
}),
|
|
325
376
|
},
|
|
326
377
|
messageFormAttachments: {
|
|
327
378
|
flexDirection: 'row',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message_form.js","sourceRoot":"","sources":["../../../src/components/conversation/message_form.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n RouteProp,\n useNavigation,\n useTheme as useNavigationTheme,\n useRoute,\n} from '@react-navigation/native'\nimport React, { useCallback, useContext, useEffect, useState } from 'react'\nimport { StyleSheet, TextInput, View, ViewProps } from 'react-native'\nimport { IconButton, Text } from '../../components'\nimport { useTheme } from '../../hooks'\nimport { ConversationResource, MessageResource } from '../../types'\n\nimport { ConversationScreenProps } from '../../screens/conversation_screen'\n\nimport { ChatContext } from '../../contexts/chat_context'\nimport { ImagePicker, ImagePickerResult } from '../../utils/native_adapters'\nimport { useAttachmentUploader } from '../../hooks/use_attachment_uploader'\nimport {\n DenormalizedAttachmentResourceForCreate,\n DenormalizedMessageAttachmentResourceForCreate,\n} from '../../types/resources/denormalized_attachment_resource'\nimport { MessageFormAttachmentImage } from './message_form/message_form_attachment_image'\nimport { useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update'\nimport { useBroadcastTypingStatus } from '../../hooks/use_broadcast_typing_status'\n\nexport const MessageForm = {\n Root: MessageFormRoot,\n\n TextInput: MessageFormInput,\n SubmitButton: MessageFormSubmitBtn,\n AttachmentPicker: MessageFormAttachmentPicker,\n Commands: MessageFormCommands,\n}\n\ninterface MessagesFormRootProps extends ViewProps {\n conversation: ConversationResource\n currentlyEditingMessage?: MessageResource | null\n}\n\nconst MessageFormContext = React.createContext<{\n text: string\n setText: (text: string) => void\n onSubmit: () => void\n disabled: boolean\n canGiphy: boolean\n usingGiphy: boolean\n setUsingGiphy: (usingGiphy: boolean) => void\n attachmentUploader?: ReturnType<typeof useAttachmentUploader>\n currentlyEditingMessage?: MessageResource | null\n}>({\n text: '',\n setText: (_text: string) => {},\n onSubmit: () => {},\n disabled: false,\n canGiphy: false,\n usingGiphy: false,\n setUsingGiphy: (_usingGiphy: boolean) => {},\n currentlyEditingMessage: null,\n})\n\nconst GIPHY_MAX_LENGTH = 50\nconst MAX_MESSAGE_LENGTH = 5000\n\nfunction MessageFormRoot({\n conversation,\n currentlyEditingMessage,\n children,\n}: MessagesFormRootProps) {\n const { giphyApiKey } = useContext(ChatContext)\n const canGiphy = !!giphyApiKey && !currentlyEditingMessage\n const styles = useMessageFormStyles()\n const [text, setText] = React.useState('')\n const [usingGiphy, setUsingGiphy] = useState(false)\n const navigation = useNavigation()\n const route = useRoute() as ConversationScreenProps['route']\n const {\n status,\n isPending,\n reset: resetMutation,\n mutateAsync,\n } = useMessageCreateOrUpdate({\n conversationId: conversation.id,\n messageId: currentlyEditingMessage?.id || null,\n })\n const attachmentUploader = useAttachmentUploader({\n conversationId: conversation.id,\n })\n const resetAttachmentUploader = attachmentUploader.reset\n\n const reset = useCallback(() => {\n resetAttachmentUploader()\n resetMutation()\n setText('')\n setUsingGiphy(false)\n navigation.setParams({\n editing_message_id: null,\n })\n }, [resetAttachmentUploader, resetMutation, navigation])\n\n useEffect(() => {\n if (canGiphy && !usingGiphy && text.startsWith('/giphy ')) {\n setUsingGiphy(true)\n setText('')\n }\n }, [canGiphy, text, usingGiphy])\n\n useEffect(() => {\n switch (status) {\n case 'success':\n reset()\n break\n }\n }, [reset, status])\n\n useEffect(() => {\n if (route.params.clear_input) {\n reset()\n navigation.setParams({ ...route.params, clear_input: false })\n }\n }, [reset, navigation, route.params])\n\n const canSubmit = (() => {\n if (isPending) return false\n if (attachmentUploader?.pendingUploads) return false\n if (text.length > 0) return true\n if (attachmentUploader?.attachments?.length) return true\n return false\n })()\n const disabled = !canSubmit\n\n const handleSubmit = () => {\n if (!canSubmit) return\n\n if (canGiphy && usingGiphy) {\n TextInput.State.blurTextInput(TextInput.State.currentlyFocusedInput())\n navigation.navigate('SendGiphy', {\n conversation_id: conversation.id,\n search_term: text,\n })\n } else {\n let attachmentsForSubmit: DenormalizedAttachmentResourceForCreate[] = []\n if (attachmentUploader?.attachmentIds) {\n attachmentsForSubmit = attachmentUploader.attachmentIds.map(\n (id: string): DenormalizedMessageAttachmentResourceForCreate => ({\n type: 'MessageAttachment',\n id,\n })\n )\n }\n if (currentlyEditingMessage) {\n mutateAsync({ text }).then(reset)\n } else {\n mutateAsync({ text, attachments: attachmentsForSubmit }).then(reset)\n }\n }\n }\n\n useEffect(() => {\n if (currentlyEditingMessage) {\n setText(currentlyEditingMessage.text || '')\n }\n }, [currentlyEditingMessage])\n\n return (\n <MessageFormContext.Provider\n value={{\n text,\n setText,\n onSubmit: handleSubmit,\n disabled,\n canGiphy,\n usingGiphy,\n setUsingGiphy,\n attachmentUploader,\n currentlyEditingMessage,\n }}\n >\n <View style={styles.container}>\n <EditingIndicator />\n <View style={styles.textInputContainer}>{children}</View>\n </View>\n </MessageFormContext.Provider>\n )\n}\n\nfunction MessageFormAttachments() {\n const styles = useMessageFormStyles()\n const { attachmentUploader } = React.useContext(MessageFormContext)\n const numberOfAttachments = attachmentUploader?.attachments?.length || 0\n const attachments = attachmentUploader?.attachments || []\n\n if (numberOfAttachments === 0) {\n return null\n }\n\n return (\n <View style={styles.messageFormAttachments}>\n {attachments.map(attachment => {\n return (\n <MessageFormAttachmentImage\n key={attachment.file.uri}\n uri={attachment.file.uri}\n alt={attachment.file.name}\n status={attachment.status}\n width={attachment.file.width}\n height={attachment.file.height}\n removeAttachment={() => {\n attachmentUploader?.removeAttachment(attachment)\n }}\n />\n )\n })}\n </View>\n )\n}\n\nfunction MessageFormInput() {\n const styles = useMessageFormStyles()\n const { text, setText, onSubmit, usingGiphy, attachmentUploader } =\n React.useContext(MessageFormContext)\n const attachmentError = attachmentUploader?.errorMessage\n\n const route = useRoute<RouteProp<ConversationScreenProps['route']>>()\n const conversationId = route.params.conversation_id\n const broadcastTypingStatus = useBroadcastTypingStatus(conversationId)\n\n const handleTextChange = (newText: string) => {\n setText(newText)\n\n if (newText.length > 0) {\n broadcastTypingStatus()\n }\n }\n\n return (\n <View style={styles.textInputBoundary}>\n <MessageFormAttachments />\n <View style={styles.textInputRow}>\n {usingGiphy ? (\n <View style={styles.giphyBadge}>\n <Text style={styles.giphyBadgeText}>/giphy</Text>\n </View>\n ) : null}\n\n <TextInput\n style={[styles.textInput, usingGiphy && styles.textInputWithGiphy]}\n multiline={true}\n aria-disabled={true}\n placeholder=\"Send a message\"\n onChangeText={handleTextChange}\n value={text}\n maxLength={usingGiphy ? GIPHY_MAX_LENGTH : MAX_MESSAGE_LENGTH}\n onSubmitEditing={onSubmit}\n />\n </View>\n\n {attachmentError ? <Text style={styles.inputErrorMessage}>{attachmentError}</Text> : null}\n </View>\n )\n}\n\nfunction MessageFormSubmitBtn() {\n const styles = useMessageFormStyles()\n const { onSubmit, disabled, usingGiphy } = React.useContext(MessageFormContext)\n\n return (\n <IconButton\n disabled={disabled}\n accessibilityLabel={usingGiphy ? 'Search Giphy' : 'Send message'}\n size=\"md\"\n appearance=\"neutral\"\n style={styles.textInputSend}\n name={usingGiphy ? 'general.search' : 'general.upArrow'}\n onPress={onSubmit}\n />\n )\n}\n\nfunction MessageFormAttachmentPicker() {\n const styles = useMessageFormStyles()\n const { usingGiphy, attachmentUploader, currentlyEditingMessage } =\n React.useContext(MessageFormContext)\n const [isOpen, setIsOpen] = useState(false)\n\n function uploadImagePickerResult(result: ImagePickerResult) {\n if (result.canceled) {\n return\n }\n\n const filteredAssets = result.assets\n .filter(asset => {\n return asset.fileSize && asset.fileName && asset.mimeType\n })\n .map(asset => {\n return {\n uri: asset.uri,\n name: asset.fileName as string,\n type: asset.mimeType as string,\n size: asset.fileSize as number,\n height: asset.height,\n width: asset.width,\n }\n })\n\n attachmentUploader?.handleFilesAttached(filteredAssets)\n }\n\n const openCamera = async () => {\n setIsOpen(false)\n let result = await ImagePicker.openCameraAsync()\n if (!result.canceled) {\n uploadImagePickerResult(result)\n }\n }\n\n const pickImage = async () => {\n setIsOpen(false)\n let result = await ImagePicker.openImageLibraryAsync()\n if (!result.canceled) {\n uploadImagePickerResult(result)\n }\n }\n\n if (usingGiphy || currentlyEditingMessage) {\n return null\n }\n\n return (\n // TODO: Design Pass\n <View style={styles.attachmentPicker}>\n {isOpen && (\n <View style={styles.attachmentPickerButtons}>\n <IconButton\n accessibilityLabel=\"Take a photo\"\n size=\"md\"\n appearance=\"neutral\"\n name={'general.videoCamera'}\n onPress={openCamera}\n />\n <IconButton\n accessibilityLabel=\"Choose a photo\"\n size=\"md\"\n appearance=\"neutral\"\n name={'churchCenter.photosIos'}\n onPress={pickImage}\n />\n </View>\n )}\n <IconButton\n accessibilityLabel=\"File Menu\"\n size=\"md\"\n appearance=\"neutral\"\n name={'general.outlinedPlusCircle'}\n onPress={() => setIsOpen(!isOpen)}\n style={styles.formButton}\n />\n </View>\n )\n}\n\nfunction MessageFormCommands() {\n const { text, canGiphy, usingGiphy, setUsingGiphy } = React.useContext(MessageFormContext)\n const styles = useMessageFormStyles()\n\n if (!canGiphy) {\n return null\n }\n\n if (usingGiphy) {\n return (\n <IconButton\n accessibilityLabel=\"Exit Giphy Search\"\n size=\"md\"\n appearance=\"neutral\"\n name={'general.x'}\n onPress={() => setUsingGiphy(false)}\n style={styles.formButton}\n />\n )\n }\n\n return (\n <IconButton\n accessibilityLabel=\"Search Giphy\"\n size=\"md\"\n appearance=\"neutral\"\n name={'general.bolt'}\n onPress={() => setUsingGiphy(true)}\n disabled={text.length > GIPHY_MAX_LENGTH}\n style={styles.formButton}\n />\n )\n}\n\nfunction EditingIndicator() {\n const { currentlyEditingMessage } = React.useContext(MessageFormContext)\n const styles = useMessageFormStyles()\n const navigation = useNavigation()\n\n if (!currentlyEditingMessage) {\n return null\n }\n\n return (\n <View style={styles.editingIndicator}>\n <Text>Editing message</Text>\n <IconButton\n accessibilityLabel=\"Exit message editing\"\n name={'general.x'}\n onPress={() => navigation.setParams({ editing_message_id: null })}\n />\n </View>\n )\n}\n\nconst useMessageFormStyles = () => {\n const theme = useTheme()\n const navigationTheme = useNavigationTheme()\n const buttonSize = 36\n\n return StyleSheet.create({\n container: {\n borderColor: theme.colors.fillColorNeutral050Base,\n borderTopWidth: 1,\n padding: 12,\n },\n textInputContainer: {\n backgroundColor: navigationTheme.colors.card,\n flexDirection: 'row',\n alignItems: 'flex-end',\n gap: 12,\n },\n textInputBoundary: {\n borderRadius: 24,\n borderWidth: 1,\n borderColor: theme.colors.fillColorNeutral050Base,\n flex: 1,\n gap: 12,\n },\n textInputRow: {\n flexDirection: 'row',\n gap: 12,\n alignItems: 'center',\n },\n textInput: {\n paddingVertical: 8,\n paddingHorizontal: 20,\n color: theme.colors.textColorDefaultPrimary,\n textAlignVertical: 'center',\n justifyContent: 'center',\n flex: 1,\n fontSize: 16,\n maxHeight: 200,\n },\n textInputWithGiphy: {\n paddingLeft: 0,\n },\n giphyBadge: {\n backgroundColor: theme.colors.fillColorNeutral050Base,\n borderRadius: 24,\n paddingHorizontal: 12,\n marginLeft: 12,\n padding: 4,\n },\n giphyBadgeText: {\n fontSize: 14,\n color: theme.colors.interaction,\n },\n formButton: {\n height: buttonSize,\n },\n textInputSend: {\n borderRadius: 24,\n height: buttonSize,\n width: buttonSize,\n },\n attachmentPicker: {\n position: 'relative',\n },\n attachmentPickerButtons: {\n position: 'absolute',\n left: 0,\n bottom: 40,\n zIndex: 10,\n gap: 16,\n },\n messageFormAttachments: {\n flexDirection: 'row',\n gap: 8,\n },\n inputErrorMessage: {\n color: theme.colors.statusErrorText,\n fontSize: 14,\n },\n editingIndicator: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n paddingBottom: 12,\n },\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"message_form.js","sourceRoot":"","sources":["../../../src/components/conversation/message_form.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EACb,QAAQ,IAAI,kBAAkB,EAC9B,QAAQ,GACT,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3E,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAa,MAAM,cAAc,CAAA;AAC1F,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,EAAE,2BAA2B,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAKnE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,WAAW,EAAqB,MAAM,6BAA6B,CAAA;AAC5E,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAA;AAK3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,8CAA8C,CAAA;AACzF,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAA;AACnF,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAA;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAA;AACrD,OAAO,cAAc,MAAM,8BAA8B,CAAA;AAEzD,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,eAAe;IAErB,SAAS,EAAE,gBAAgB;IAC3B,YAAY,EAAE,oBAAoB;IAClC,gBAAgB,EAAE,2BAA2B;IAC7C,QAAQ,EAAE,mBAAmB;CAC9B,CAAA;AAOD,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CAU3C;IACD,IAAI,EAAE,EAAE;IACR,OAAO,EAAE,CAAC,KAAa,EAAE,EAAE,GAAE,CAAC;IAC9B,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;IAClB,QAAQ,EAAE,KAAK;IACf,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,KAAK;IACjB,aAAa,EAAE,CAAC,WAAoB,EAAE,EAAE,GAAE,CAAC;IAC3C,uBAAuB,EAAE,IAAI;CAC9B,CAAC,CAAA;AAEF,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAC3B,MAAM,kBAAkB,GAAG,IAAI,CAAA;AAE/B,SAAS,eAAe,CAAC,EACvB,YAAY,EACZ,uBAAuB,EACvB,QAAQ,GACc;IACtB,MAAM,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IAC/C,MAAM,QAAQ,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,uBAAuB,CAAA;IAC1D,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC1C,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAClC,MAAM,KAAK,GAAG,QAAQ,EAAsC,CAAA;IAC5D,MAAM,EACJ,MAAM,EACN,SAAS,EACT,KAAK,EAAE,aAAa,EACpB,WAAW,GACZ,GAAG,wBAAwB,CAAC;QAC3B,cAAc,EAAE,YAAY,CAAC,EAAE;QAC/B,SAAS,EAAE,uBAAuB,EAAE,EAAE,IAAI,IAAI;KAC/C,CAAC,CAAA;IACF,MAAM,kBAAkB,GAAG,qBAAqB,CAAC;QAC/C,cAAc,EAAE,YAAY,CAAC,EAAE;KAChC,CAAC,CAAA;IACF,MAAM,uBAAuB,GAAG,kBAAkB,CAAC,KAAK,CAAA;IAExD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,uBAAuB,EAAE,CAAA;QACzB,aAAa,EAAE,CAAA;QACf,OAAO,CAAC,EAAE,CAAC,CAAA;QACX,aAAa,CAAC,KAAK,CAAC,CAAA;QACpB,UAAU,CAAC,SAAS,CAAC;YACnB,kBAAkB,EAAE,IAAI;SACzB,CAAC,CAAA;IACJ,CAAC,EAAE,CAAC,uBAAuB,EAAE,aAAa,EAAE,UAAU,CAAC,CAAC,CAAA;IAExD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1D,aAAa,CAAC,IAAI,CAAC,CAAA;YACnB,OAAO,CAAC,EAAE,CAAC,CAAA;QACb,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAA;IAEhC,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,SAAS;gBACZ,KAAK,EAAE,CAAA;gBACP,MAAK;QACT,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;IAEnB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC7B,KAAK,EAAE,CAAA;YACP,UAAU,CAAC,SAAS,CAAC,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAA;QAC/D,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;IAErC,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE;QACtB,IAAI,SAAS;YAAE,OAAO,KAAK,CAAA;QAC3B,IAAI,kBAAkB,EAAE,cAAc;YAAE,OAAO,KAAK,CAAA;QACpD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;QAChC,IAAI,kBAAkB,EAAE,WAAW,EAAE,MAAM;YAAE,OAAO,IAAI,CAAA;QACxD,OAAO,KAAK,CAAA;IACd,CAAC,CAAC,EAAE,CAAA;IACJ,MAAM,QAAQ,GAAG,CAAC,SAAS,CAAA;IAE3B,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,IAAI,CAAC,SAAS;YAAE,OAAM;QAEtB,IAAI,QAAQ,IAAI,UAAU,EAAE,CAAC;YAC3B,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAA;YACtE,UAAU,CAAC,QAAQ,CAAC,WAAW,EAAE;gBAC/B,eAAe,EAAE,YAAY,CAAC,EAAE;gBAChC,WAAW,EAAE,IAAI;aAClB,CAAC,CAAA;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,oBAAoB,GAA8C,EAAE,CAAA;YACxE,IAAI,kBAAkB,EAAE,aAAa,EAAE,CAAC;gBACtC,oBAAoB,GAAG,kBAAkB,CAAC,aAAa,CAAC,GAAG,CACzD,CAAC,EAAU,EAAkD,EAAE,CAAC,CAAC;oBAC/D,IAAI,EAAE,mBAAmB;oBACzB,EAAE;iBACH,CAAC,CACH,CAAA;YACH,CAAC;YACD,IAAI,uBAAuB,EAAE,CAAC;gBAC5B,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACnC,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACtE,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,uBAAuB,EAAE,CAAC;YAC5B,OAAO,CAAC,uBAAuB,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAA;IAE7B,OAAO,CACL,CAAC,kBAAkB,CAAC,QAAQ,CAC1B,KAAK,CAAC,CAAC;YACL,IAAI;YACJ,OAAO;YACP,QAAQ,EAAE,YAAY;YACtB,QAAQ;YACR,QAAQ;YACR,UAAU;YACV,aAAa;YACb,kBAAkB;YAClB,uBAAuB;SACxB,CAAC,CAEF;MAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAC5B;QAAA,CAAC,gBAAgB,CAAC,AAAD,EACjB;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,CAC1D;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAC/B,CAAA;AACH,CAAC;AAED,SAAS,sBAAsB;IAC7B,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,MAAM,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;IACnE,MAAM,mBAAmB,GAAG,kBAAkB,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC,CAAA;IACxE,MAAM,WAAW,GAAG,kBAAkB,EAAE,WAAW,IAAI,EAAE,CAAA;IAEzD,IAAI,mBAAmB,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,sBAAsB,CAAC,CACzC;MAAA,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;YAC5B,OAAO,CACL,CAAC,0BAA0B,CACzB,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CACzB,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CACzB,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAC1B,MAAM,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAC1B,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAC7B,MAAM,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAC/B,gBAAgB,CAAC,CAAC,GAAG,EAAE;oBACrB,kBAAkB,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAA;gBAClD,CAAC,CAAC,EACF,CACH,CAAA;QACH,CAAC,CAAC,CACJ;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC;AAED,SAAS,gBAAgB;IACvB,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IACxB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,kBAAkB,EAAE,GAC/D,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;IACtC,MAAM,eAAe,GAAG,kBAAkB,EAAE,YAAY,CAAA;IAExD,MAAM,KAAK,GAAG,QAAQ,EAA+C,CAAA;IACrE,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,eAAe,CAAA;IACnD,MAAM,qBAAqB,GAAG,wBAAwB,CAAC,cAAc,CAAC,CAAA;IAEtE,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAE,EAAE;QAC3C,OAAO,CAAC,OAAO,CAAC,CAAA;QAEhB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,qBAAqB,EAAE,CAAA;QACzB,CAAC;IACH,CAAC,CAAA;IAED,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CACpC;MAAA,CAAC,sBAAsB,CAAC,AAAD,EACvB;MAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAC/B;QAAA,CAAC,UAAU,CAAC,CAAC,CAAC,CACZ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAC7B;YAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,IAAI,CAClD;UAAA,EAAE,IAAI,CAAC,CACR,CAAC,CAAC,CAAC,IAAI,CAER;;QAAA,CAAC,SAAS,CACR,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,IAAI,MAAM,CAAC,kBAAkB,CAAC,CAAC,CACnE,SAAS,CAAC,CAAC,IAAI,CAAC,CAChB,aAAa,CAAC,CAAC,IAAI,CAAC,CACpB,WAAW,CAAC,gBAAgB,CAC5B,oBAAoB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAC/D,YAAY,CAAC,CAAC,gBAAgB,CAAC,CAC/B,KAAK,CAAC,CAAC,IAAI,CAAC,CACZ,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAC9D,eAAe,CAAC,CAAC,QAAQ,CAAC,EAE9B;MAAA,EAAE,IAAI,CAEN;;MAAA,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAC3F;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC;AAED,SAAS,oBAAoB;IAC3B,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;IAC/E,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAE7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAA;IACtD,MAAM,gBAAgB,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAA;IACjE,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,WAAW,CAAA;IAC7D,MAAM,QAAQ,GAAG;QACf,QAAQ,EAAE;YACR,MAAM,CAAC,mCAAmC;YAC1C,MAAM,CAAC,mCAAmC;SAC3C;QACD,WAAW,EAAE,CAAC,gBAAgB,EAAE,cAAc,CAAC;KAChD,CAAA;IAED,MAAM,kBAAkB,GAAG,2BAA2B,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IACxF,MAAM,cAAc,GAAG,QAAQ,CAAC,QAAQ,CAAqB,CAAA;IAC7D,MAAM,UAAU,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,IAAI,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAE7E,OAAO,CACL,CAAC,SAAS,CACR,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,OAAO,CAAC,CAAC,QAAQ,CAAC,CAClB,iBAAiB,CAAC,QAAQ,CAC1B,kBAAkB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CACjE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACtB,MAAM,CAAC,sBAAsB;YAC7B,OAAO,IAAI,2BAA2B;SACvC,CAAC,CACF,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAEnF;MAAA,CAAC,cAAc,CACb,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAC1B,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CACxB,MAAM,CAAC,CAAC,cAAc,CAAC,CACvB,KAAK,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAEpC;QAAA,CAAC,IAAI,CACH,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CACxD,KAAK,CAAC,CAAC,UAAU,CAAC,CAClB,2BAA2B,CAAC,CAAC,IAAI,CAAC,EAEtC;MAAA,EAAE,cAAc,CAClB;IAAA,EAAE,SAAS,CAAC,CACb,CAAA;AACH,CAAC;AAED,SAAS,2BAA2B;IAClC,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,MAAM,EAAE,UAAU,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,GAC/D,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;IACtC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE3C,SAAS,uBAAuB,CAAC,MAAyB;QACxD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM;aACjC,MAAM,CAAC,KAAK,CAAC,EAAE;YACd,OAAO,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAA;QAC3D,CAAC,CAAC;aACD,GAAG,CAAC,KAAK,CAAC,EAAE;YACX,OAAO;gBACL,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,IAAI,EAAE,KAAK,CAAC,QAAkB;gBAC9B,IAAI,EAAE,KAAK,CAAC,QAAkB;gBAC9B,IAAI,EAAE,KAAK,CAAC,QAAkB;gBAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;aACnB,CAAA;QACH,CAAC,CAAC,CAAA;QAEJ,kBAAkB,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAA;IACzD,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,IAAI,EAAE;QAC5B,SAAS,CAAC,KAAK,CAAC,CAAA;QAChB,IAAI,MAAM,GAAG,MAAM,WAAW,CAAC,eAAe,EAAE,CAAA;QAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,uBAAuB,CAAC,MAAM,CAAC,CAAA;QACjC,CAAC;IACH,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;QAC3B,SAAS,CAAC,KAAK,CAAC,CAAA;QAChB,IAAI,MAAM,GAAG,MAAM,WAAW,CAAC,qBAAqB,EAAE,CAAA;QACtD,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,uBAAuB,CAAC,MAAM,CAAC,CAAA;QACjC,CAAC;IACH,CAAC,CAAA;IAED,IAAI,UAAU,IAAI,uBAAuB,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CACnC;MAAA,CAAC,MAAM,IAAI,CACT,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,gCAAgC,CAAC,CACnD;UAAA,CAAC,UAAU,CACT,kBAAkB,CAAC,cAAc,CACjC,iBAAiB,CAAC,mBAAmB,CACrC,IAAI,CAAC,IAAI,CACT,UAAU,CAAC,SAAS,CACpB,IAAI,CAAC,qBAAqB,CAC1B,OAAO,CAAC,CAAC,UAAU,CAAC,CACpB,KAAK,CAAC,CAAC,MAAM,CAAC,sBAAsB,CAAC,EAEvC;UAAA,CAAC,UAAU,CACT,kBAAkB,CAAC,gBAAgB,CACnC,iBAAiB,CAAC,0BAA0B,CAC5C,IAAI,CAAC,IAAI,CACT,UAAU,CAAC,SAAS,CACpB,IAAI,CAAC,wBAAwB,CAC7B,OAAO,CAAC,CAAC,SAAS,CAAC,CACnB,KAAK,CAAC,CAAC,MAAM,CAAC,sBAAsB,CAAC,EAEzC;QAAA,EAAE,IAAI,CAAC,CACR,CACD;MAAA,CAAC,UAAU,CACT,kBAAkB,CAAC,WAAW,CAC9B,iBAAiB,CAAC,yCAAyC,CAC3D,IAAI,CAAC,IAAI,CACT,UAAU,CAAC,SAAS,CACpB,IAAI,CAAC,mBAAmB,CACxB,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAClC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EAE7B;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;IAC1F,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IAErC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CACL,CAAC,UAAU,CACT,kBAAkB,CAAC,mBAAmB,CACtC,IAAI,CAAC,IAAI,CACT,UAAU,CAAC,SAAS,CACpB,IAAI,CAAC,CAAC,WAAW,CAAC,CAClB,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CACpC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EACzB,CACH,CAAA;IACH,CAAC;IAED,OAAO,CACL,CAAC,UAAU,CACT,kBAAkB,CAAC,cAAc,CACjC,IAAI,CAAC,IAAI,CACT,UAAU,CAAC,SAAS,CACpB,IAAI,CAAC,CAAC,cAAc,CAAC,CACrB,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CACnC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,gBAAgB,CAAC,CACzC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EACzB,CACH,CAAA;AACH,CAAC;AAED,SAAS,gBAAgB;IACvB,MAAM,EAAE,uBAAuB,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;IACxE,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAA;IACrC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAElC,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CACnC;MAAA,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAC3B;MAAA,CAAC,UAAU,CACT,kBAAkB,CAAC,sBAAsB,CACzC,IAAI,CAAC,CAAC,WAAW,CAAC,CAClB,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,EAEtE;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC;AAED,MAAM,oBAAoB,GAAG,GAAG,EAAE;IAChC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IACxB,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAA;IAC5C,MAAM,UAAU,GAAG,EAAE,CAAA;IAErB,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,SAAS,EAAE;YACT,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,uBAAuB;YACjD,cAAc,EAAE,CAAC;YACjB,OAAO,EAAE,EAAE;SACZ;QACD,kBAAkB,EAAE;YAClB,eAAe,EAAE,eAAe,CAAC,MAAM,CAAC,IAAI;YAC5C,aAAa,EAAE,KAAK;YACpB,UAAU,EAAE,UAAU;YACtB,GAAG,EAAE,EAAE;SACR;QACD,iBAAiB,EAAE;YACjB,YAAY,EAAE,EAAE;YAChB,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,uBAAuB;YACjD,IAAI,EAAE,CAAC;YACP,GAAG,EAAE,EAAE;SACR;QACD,YAAY,EAAE;YACZ,aAAa,EAAE,KAAK;YACpB,GAAG,EAAE,EAAE;YACP,UAAU,EAAE,QAAQ;SACrB;QACD,SAAS,EAAE;YACT,eAAe,EAAE,CAAC;YAClB,iBAAiB,EAAE,EAAE;YACrB,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,uBAAuB;YAC3C,iBAAiB,EAAE,QAAQ;YAC3B,cAAc,EAAE,QAAQ;YACxB,IAAI,EAAE,CAAC;YACP,QAAQ,EAAE,EAAE;YACZ,SAAS,EAAE,GAAG;SACf;QACD,kBAAkB,EAAE;YAClB,WAAW,EAAE,CAAC;SACf;QACD,UAAU,EAAE;YACV,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,uBAAuB;YACrD,YAAY,EAAE,EAAE;YAChB,iBAAiB,EAAE,EAAE;YACrB,UAAU,EAAE,EAAE;YACd,OAAO,EAAE,CAAC;SACX;QACD,cAAc,EAAE;YACd,QAAQ,EAAE,EAAE;YACZ,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW;SAChC;QACD,UAAU,EAAE;YACV,MAAM,EAAE,UAAU;SACnB;QACD,sBAAsB,EAAE;YACtB,YAAY,EAAE,UAAU;YACxB,QAAQ,EAAE,QAAQ;SACnB;QACD,qBAAqB,EAAE;YACrB,aAAa,EAAE,KAAK;YACpB,cAAc,EAAE,QAAQ;YACxB,UAAU,EAAE,QAAQ;YACpB,YAAY,EAAE,UAAU;YACxB,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,UAAU;SAClB;QACD,UAAU,EAAE;YACV,QAAQ,EAAE,EAAE;YACZ,KAAK,EAAE,MAAM,CAAC,oBAAoB;SACnC;QACD,kBAAkB,EAAE;YAClB,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,wBAAwB;SAC7C;QACD,gBAAgB,EAAE;YAChB,QAAQ,EAAE,UAAU;SACrB;QACD,gCAAgC,EAAE;YAChC,QAAQ,EAAE,UAAU;YACpB,IAAI,EAAE,CAAC;YACP,MAAM,EAAE,EAAE;YACV,MAAM,EAAE,EAAE;YACV,GAAG,EAAE,EAAE;SACR;QACD,sBAAsB,EAAE;YACtB,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,mBAAmB;YACjD,YAAY,EAAE,EAAE;YAChB,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,UAAU;YACjB,SAAS,EAAE,CAAC;YACZ,GAAG,QAAQ,CAAC,MAAM,CAAC;gBACjB,GAAG,EAAE;oBACH,WAAW,EAAE,CAAC;oBACd,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,sBAAsB;iBACjD;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;SACH;QACD,sBAAsB,EAAE;YACtB,aAAa,EAAE,KAAK;YACpB,GAAG,EAAE,CAAC;SACP;QACD,iBAAiB,EAAE;YACjB,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,eAAe;YACnC,QAAQ,EAAE,EAAE;SACb;QACD,gBAAgB,EAAE;YAChB,aAAa,EAAE,KAAK;YACpB,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,QAAQ;YACxB,GAAG,EAAE,CAAC;YACN,aAAa,EAAE,EAAE;SAClB;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import {\n RouteProp,\n useNavigation,\n useTheme as useNavigationTheme,\n useRoute,\n} from '@react-navigation/native'\nimport React, { useCallback, useContext, useEffect, useState } from 'react'\nimport { Platform, Pressable, StyleSheet, TextInput, View, ViewProps } from 'react-native'\nimport { Icon, IconButton, Text } from '../../components'\nimport { useCreateAndroidRippleColor, useTheme } from '../../hooks'\nimport { ConversationResource, MessageResource } from '../../types'\n\nimport { ConversationScreenProps } from '../../screens/conversation_screen'\n\nimport { ChatContext } from '../../contexts/chat_context'\nimport { ImagePicker, ImagePickerResult } from '../../utils/native_adapters'\nimport { platformPressedOpacityStyle } from '../../utils'\nimport { useAttachmentUploader } from '../../hooks/use_attachment_uploader'\nimport {\n DenormalizedAttachmentResourceForCreate,\n DenormalizedMessageAttachmentResourceForCreate,\n} from '../../types/resources/denormalized_attachment_resource'\nimport { MessageFormAttachmentImage } from './message_form/message_form_attachment_image'\nimport { useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update'\nimport { useBroadcastTypingStatus } from '../../hooks/use_broadcast_typing_status'\nimport { tokens } from '../../vendor/tapestry/tokens'\nimport LinearGradient from 'react-native-linear-gradient'\n\nexport const MessageForm = {\n Root: MessageFormRoot,\n\n TextInput: MessageFormInput,\n SubmitButton: MessageFormSubmitBtn,\n AttachmentPicker: MessageFormAttachmentPicker,\n Commands: MessageFormCommands,\n}\n\ninterface MessagesFormRootProps extends ViewProps {\n conversation: ConversationResource\n currentlyEditingMessage?: MessageResource | null\n}\n\nconst MessageFormContext = React.createContext<{\n text: string\n setText: (text: string) => void\n onSubmit: () => void\n disabled: boolean\n canGiphy: boolean\n usingGiphy: boolean\n setUsingGiphy: (usingGiphy: boolean) => void\n attachmentUploader?: ReturnType<typeof useAttachmentUploader>\n currentlyEditingMessage?: MessageResource | null\n}>({\n text: '',\n setText: (_text: string) => {},\n onSubmit: () => {},\n disabled: false,\n canGiphy: false,\n usingGiphy: false,\n setUsingGiphy: (_usingGiphy: boolean) => {},\n currentlyEditingMessage: null,\n})\n\nconst GIPHY_MAX_LENGTH = 50\nconst MAX_MESSAGE_LENGTH = 5000\n\nfunction MessageFormRoot({\n conversation,\n currentlyEditingMessage,\n children,\n}: MessagesFormRootProps) {\n const { giphyApiKey } = useContext(ChatContext)\n const canGiphy = !!giphyApiKey && !currentlyEditingMessage\n const styles = useMessageFormStyles()\n const [text, setText] = React.useState('')\n const [usingGiphy, setUsingGiphy] = useState(false)\n const navigation = useNavigation()\n const route = useRoute() as ConversationScreenProps['route']\n const {\n status,\n isPending,\n reset: resetMutation,\n mutateAsync,\n } = useMessageCreateOrUpdate({\n conversationId: conversation.id,\n messageId: currentlyEditingMessage?.id || null,\n })\n const attachmentUploader = useAttachmentUploader({\n conversationId: conversation.id,\n })\n const resetAttachmentUploader = attachmentUploader.reset\n\n const reset = useCallback(() => {\n resetAttachmentUploader()\n resetMutation()\n setText('')\n setUsingGiphy(false)\n navigation.setParams({\n editing_message_id: null,\n })\n }, [resetAttachmentUploader, resetMutation, navigation])\n\n useEffect(() => {\n if (canGiphy && !usingGiphy && text.startsWith('/giphy ')) {\n setUsingGiphy(true)\n setText('')\n }\n }, [canGiphy, text, usingGiphy])\n\n useEffect(() => {\n switch (status) {\n case 'success':\n reset()\n break\n }\n }, [reset, status])\n\n useEffect(() => {\n if (route.params.clear_input) {\n reset()\n navigation.setParams({ ...route.params, clear_input: false })\n }\n }, [reset, navigation, route.params])\n\n const canSubmit = (() => {\n if (isPending) return false\n if (attachmentUploader?.pendingUploads) return false\n if (text.length > 0) return true\n if (attachmentUploader?.attachments?.length) return true\n return false\n })()\n const disabled = !canSubmit\n\n const handleSubmit = () => {\n if (!canSubmit) return\n\n if (canGiphy && usingGiphy) {\n TextInput.State.blurTextInput(TextInput.State.currentlyFocusedInput())\n navigation.navigate('SendGiphy', {\n conversation_id: conversation.id,\n search_term: text,\n })\n } else {\n let attachmentsForSubmit: DenormalizedAttachmentResourceForCreate[] = []\n if (attachmentUploader?.attachmentIds) {\n attachmentsForSubmit = attachmentUploader.attachmentIds.map(\n (id: string): DenormalizedMessageAttachmentResourceForCreate => ({\n type: 'MessageAttachment',\n id,\n })\n )\n }\n if (currentlyEditingMessage) {\n mutateAsync({ text }).then(reset)\n } else {\n mutateAsync({ text, attachments: attachmentsForSubmit }).then(reset)\n }\n }\n }\n\n useEffect(() => {\n if (currentlyEditingMessage) {\n setText(currentlyEditingMessage.text || '')\n }\n }, [currentlyEditingMessage])\n\n return (\n <MessageFormContext.Provider\n value={{\n text,\n setText,\n onSubmit: handleSubmit,\n disabled,\n canGiphy,\n usingGiphy,\n setUsingGiphy,\n attachmentUploader,\n currentlyEditingMessage,\n }}\n >\n <View style={styles.container}>\n <EditingIndicator />\n <View style={styles.textInputContainer}>{children}</View>\n </View>\n </MessageFormContext.Provider>\n )\n}\n\nfunction MessageFormAttachments() {\n const styles = useMessageFormStyles()\n const { attachmentUploader } = React.useContext(MessageFormContext)\n const numberOfAttachments = attachmentUploader?.attachments?.length || 0\n const attachments = attachmentUploader?.attachments || []\n\n if (numberOfAttachments === 0) {\n return null\n }\n\n return (\n <View style={styles.messageFormAttachments}>\n {attachments.map(attachment => {\n return (\n <MessageFormAttachmentImage\n key={attachment.file.uri}\n uri={attachment.file.uri}\n alt={attachment.file.name}\n status={attachment.status}\n width={attachment.file.width}\n height={attachment.file.height}\n removeAttachment={() => {\n attachmentUploader?.removeAttachment(attachment)\n }}\n />\n )\n })}\n </View>\n )\n}\n\nfunction MessageFormInput() {\n const styles = useMessageFormStyles()\n const theme = useTheme()\n const { text, setText, onSubmit, usingGiphy, attachmentUploader } =\n React.useContext(MessageFormContext)\n const attachmentError = attachmentUploader?.errorMessage\n\n const route = useRoute<RouteProp<ConversationScreenProps['route']>>()\n const conversationId = route.params.conversation_id\n const broadcastTypingStatus = useBroadcastTypingStatus(conversationId)\n\n const handleTextChange = (newText: string) => {\n setText(newText)\n\n if (newText.length > 0) {\n broadcastTypingStatus()\n }\n }\n\n return (\n <View style={styles.textInputBoundary}>\n <MessageFormAttachments />\n <View style={styles.textInputRow}>\n {usingGiphy ? (\n <View style={styles.giphyBadge}>\n <Text style={styles.giphyBadgeText}>/giphy</Text>\n </View>\n ) : null}\n\n <TextInput\n style={[styles.textInput, usingGiphy && styles.textInputWithGiphy]}\n multiline={true}\n aria-disabled={true}\n placeholder=\"Send a message\"\n placeholderTextColor={theme.colors.textColorDefaultPlaceholder}\n onChangeText={handleTextChange}\n value={text}\n maxLength={usingGiphy ? GIPHY_MAX_LENGTH : MAX_MESSAGE_LENGTH}\n onSubmitEditing={onSubmit}\n />\n </View>\n\n {attachmentError ? <Text style={styles.inputErrorMessage}>{attachmentError}</Text> : null}\n </View>\n )\n}\n\nfunction MessageFormSubmitBtn() {\n const { onSubmit, disabled, usingGiphy } = React.useContext(MessageFormContext)\n const styles = useMessageFormStyles()\n const { colors } = useTheme()\n\n const colorKey = disabled ? 'disabled' : 'interaction'\n const interactionStart = colors.buttonStart || colors.interaction\n const interactionEnd = colors.buttonEnd || colors.interaction\n const colorMap = {\n disabled: [\n colors.fillColorButtonNeutralSolidDisabled,\n colors.fillColorButtonNeutralSolidDisabled,\n ],\n interaction: [interactionStart, interactionEnd],\n }\n\n const androidRippleColor = useCreateAndroidRippleColor({ color: colorMap[colorKey][0] })\n const gradientColors = colorMap[colorKey] as [string, string]\n const iconStyles = [styles.submitIcon, disabled && styles.submitIconDisabled]\n\n return (\n <Pressable\n disabled={disabled}\n onPress={onSubmit}\n accessibilityRole=\"button\"\n accessibilityLabel={usingGiphy ? 'Search Giphy' : 'Send message'}\n style={({ pressed }) => [\n styles.submitPressableWrapper,\n pressed && platformPressedOpacityStyle,\n ]}\n android_ripple={{ color: androidRippleColor, borderless: false, foreground: true }}\n >\n <LinearGradient\n start={{ x: 0.1, y: 0.1 }}\n end={{ x: 0.9, y: 0.9 }}\n colors={gradientColors}\n style={styles.submitGradientWrapper}\n >\n <Icon\n name={usingGiphy ? 'general.search' : 'general.upArrow'}\n style={iconStyles}\n accessibilityElementsHidden={true}\n />\n </LinearGradient>\n </Pressable>\n )\n}\n\nfunction MessageFormAttachmentPicker() {\n const styles = useMessageFormStyles()\n const { usingGiphy, attachmentUploader, currentlyEditingMessage } =\n React.useContext(MessageFormContext)\n const [isOpen, setIsOpen] = useState(false)\n\n function uploadImagePickerResult(result: ImagePickerResult) {\n if (result.canceled) {\n return\n }\n\n const filteredAssets = result.assets\n .filter(asset => {\n return asset.fileSize && asset.fileName && asset.mimeType\n })\n .map(asset => {\n return {\n uri: asset.uri,\n name: asset.fileName as string,\n type: asset.mimeType as string,\n size: asset.fileSize as number,\n height: asset.height,\n width: asset.width,\n }\n })\n\n attachmentUploader?.handleFilesAttached(filteredAssets)\n }\n\n const openCamera = async () => {\n setIsOpen(false)\n let result = await ImagePicker.openCameraAsync()\n if (!result.canceled) {\n uploadImagePickerResult(result)\n }\n }\n\n const pickImage = async () => {\n setIsOpen(false)\n let result = await ImagePicker.openImageLibraryAsync()\n if (!result.canceled) {\n uploadImagePickerResult(result)\n }\n }\n\n if (usingGiphy || currentlyEditingMessage) {\n return null\n }\n\n return (\n <View style={styles.attachmentPicker}>\n {isOpen && (\n <View style={styles.attachmentPickerButtonsContainer}>\n <IconButton\n accessibilityLabel=\"Take a photo\"\n accessibilityHint=\"Opens your camera\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"general.videoCamera\"\n onPress={openCamera}\n style={styles.attachmentPickerButton}\n />\n <IconButton\n accessibilityLabel=\"Choose a photo\"\n accessibilityHint=\"Opens your photo gallery\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"churchCenter.photosIos\"\n onPress={pickImage}\n style={styles.attachmentPickerButton}\n />\n </View>\n )}\n <IconButton\n accessibilityLabel=\"File Menu\"\n accessibilityHint=\"Opens options to attach or take a photo\"\n size=\"lg\"\n appearance=\"neutral\"\n name=\"general.paperclip\"\n onPress={() => setIsOpen(!isOpen)}\n style={styles.formButton}\n />\n </View>\n )\n}\n\nfunction MessageFormCommands() {\n const { text, canGiphy, usingGiphy, setUsingGiphy } = React.useContext(MessageFormContext)\n const styles = useMessageFormStyles()\n\n if (!canGiphy) {\n return null\n }\n\n if (usingGiphy) {\n return (\n <IconButton\n accessibilityLabel=\"Exit Giphy Search\"\n size=\"md\"\n appearance=\"neutral\"\n name={'general.x'}\n onPress={() => setUsingGiphy(false)}\n style={styles.formButton}\n />\n )\n }\n\n return (\n <IconButton\n accessibilityLabel=\"Search Giphy\"\n size=\"lg\"\n appearance=\"neutral\"\n name={'general.bolt'}\n onPress={() => setUsingGiphy(true)}\n disabled={text.length > GIPHY_MAX_LENGTH}\n style={styles.formButton}\n />\n )\n}\n\nfunction EditingIndicator() {\n const { currentlyEditingMessage } = React.useContext(MessageFormContext)\n const styles = useMessageFormStyles()\n const navigation = useNavigation()\n\n if (!currentlyEditingMessage) {\n return null\n }\n\n return (\n <View style={styles.editingIndicator}>\n <Text>Editing message</Text>\n <IconButton\n accessibilityLabel=\"Exit message editing\"\n name={'general.x'}\n onPress={() => navigation.setParams({ editing_message_id: null })}\n />\n </View>\n )\n}\n\nconst useMessageFormStyles = () => {\n const theme = useTheme()\n const navigationTheme = useNavigationTheme()\n const buttonSize = 38\n\n return StyleSheet.create({\n container: {\n borderColor: theme.colors.fillColorNeutral050Base,\n borderTopWidth: 1,\n padding: 12,\n },\n textInputContainer: {\n backgroundColor: navigationTheme.colors.card,\n flexDirection: 'row',\n alignItems: 'flex-end',\n gap: 16,\n },\n textInputBoundary: {\n borderRadius: 24,\n borderWidth: 1,\n borderColor: theme.colors.fillColorNeutral050Base,\n flex: 1,\n gap: 12,\n },\n textInputRow: {\n flexDirection: 'row',\n gap: 12,\n alignItems: 'center',\n },\n textInput: {\n paddingVertical: 8,\n paddingHorizontal: 16,\n color: theme.colors.textColorDefaultPrimary,\n textAlignVertical: 'center',\n justifyContent: 'center',\n flex: 1,\n fontSize: 16,\n maxHeight: 200,\n },\n textInputWithGiphy: {\n paddingLeft: 0,\n },\n giphyBadge: {\n backgroundColor: theme.colors.fillColorNeutral050Base,\n borderRadius: 24,\n paddingHorizontal: 12,\n marginLeft: 12,\n padding: 4,\n },\n giphyBadgeText: {\n fontSize: 14,\n color: theme.colors.interaction,\n },\n formButton: {\n height: buttonSize,\n },\n submitPressableWrapper: {\n borderRadius: buttonSize,\n overflow: 'hidden',\n },\n submitGradientWrapper: {\n flexDirection: 'row',\n justifyContent: 'center',\n alignItems: 'center',\n borderRadius: buttonSize,\n height: buttonSize,\n width: buttonSize,\n },\n submitIcon: {\n fontSize: 16,\n color: tokens.colorNeutral100White,\n },\n submitIconDisabled: {\n color: theme.colors.iconColorDefaultDisabled,\n },\n attachmentPicker: {\n position: 'relative',\n },\n attachmentPickerButtonsContainer: {\n position: 'absolute',\n left: 0,\n bottom: 40,\n zIndex: 10,\n gap: 12,\n },\n attachmentPickerButton: {\n backgroundColor: theme.colors.fillColorNeutral070,\n borderRadius: 20,\n height: buttonSize,\n width: buttonSize,\n elevation: 3,\n ...Platform.select({\n ios: {\n borderWidth: 1,\n borderColor: theme.colors.borderColorDefaultBase,\n },\n default: null,\n }),\n },\n messageFormAttachments: {\n flexDirection: 'row',\n gap: 8,\n },\n inputErrorMessage: {\n color: theme.colors.statusErrorText,\n fontSize: 14,\n },\n editingIndicator: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n paddingBottom: 12,\n },\n })\n}\n"]}
|
|
@@ -10,7 +10,7 @@ declare class ErrorBoundary extends React.Component<PropsWithChildren<{
|
|
|
10
10
|
componentDidCatch(error: any): void;
|
|
11
11
|
handleError(error: any): void;
|
|
12
12
|
handleReset: () => void;
|
|
13
|
-
render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> |
|
|
13
|
+
render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
|
|
14
14
|
}
|
|
15
15
|
export default ErrorBoundary;
|
|
16
16
|
//# sourceMappingURL=error_boundary.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../../src/utils/native_adapters/audio.ts"],"names":[],"mappings":"AAAA,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../../src/utils/native_adapters/audio.ts"],"names":[],"mappings":"AAAA,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;CACvC;AAED,qBAAa,YAAY;IACvB,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,KAAK,CAAA;gBAElB,OAAO,EAAE,YAAY;CAGlC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio.js","sourceRoot":"","sources":["../../../src/utils/native_adapters/audio.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"audio.js","sourceRoot":"","sources":["../../../src/utils/native_adapters/audio.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,YAAY;IACvB,QAAQ,CAAsB;IAE9B,YAAY,OAAqB;QAC/B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IAClC,CAAC;CACF","sourcesContent":["interface Audio {\n play: () => void\n pause: () => void\n isPlaying: boolean\n duration: number\n position: number\n AudioPlayer?: React.JSX.Element | null\n}\n\nexport class AudioAdapter {\n useAudio: (_: string) => Audio\n\n constructor(methods: AudioAdapter) {\n this.useAudio = methods.useAudio\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "3.7.0-rc.
|
|
3
|
+
"version": "3.7.0-rc.6",
|
|
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": "b872ecaf8dca621c7619ae91e856ef62f27d0d49"
|
|
59
59
|
}
|
|
@@ -20,6 +20,7 @@ export function AudioAttachment({
|
|
|
20
20
|
const { attributes } = attachment
|
|
21
21
|
const { url, filename } = attributes
|
|
22
22
|
const sound = Audio.useAudio(url)
|
|
23
|
+
const { AudioPlayer } = sound
|
|
23
24
|
|
|
24
25
|
function toggleAudio() {
|
|
25
26
|
if (!sound.isPlaying) {
|
|
@@ -39,6 +40,7 @@ export function AudioAttachment({
|
|
|
39
40
|
>
|
|
40
41
|
<AttachmentCard>
|
|
41
42
|
<View style={styles.container}>
|
|
43
|
+
{AudioPlayer}
|
|
42
44
|
<IconButton
|
|
43
45
|
name={sound.isPlaying ? 'services.pause' : 'services.play'}
|
|
44
46
|
size="md"
|
|
@@ -5,15 +5,16 @@ import {
|
|
|
5
5
|
useRoute,
|
|
6
6
|
} from '@react-navigation/native'
|
|
7
7
|
import React, { useCallback, useContext, useEffect, useState } from 'react'
|
|
8
|
-
import { StyleSheet, TextInput, View, ViewProps } from 'react-native'
|
|
9
|
-
import { IconButton, Text } from '../../components'
|
|
10
|
-
import { useTheme } from '../../hooks'
|
|
8
|
+
import { Platform, Pressable, StyleSheet, TextInput, View, ViewProps } from 'react-native'
|
|
9
|
+
import { Icon, IconButton, Text } from '../../components'
|
|
10
|
+
import { useCreateAndroidRippleColor, useTheme } from '../../hooks'
|
|
11
11
|
import { ConversationResource, MessageResource } from '../../types'
|
|
12
12
|
|
|
13
13
|
import { ConversationScreenProps } from '../../screens/conversation_screen'
|
|
14
14
|
|
|
15
15
|
import { ChatContext } from '../../contexts/chat_context'
|
|
16
16
|
import { ImagePicker, ImagePickerResult } from '../../utils/native_adapters'
|
|
17
|
+
import { platformPressedOpacityStyle } from '../../utils'
|
|
17
18
|
import { useAttachmentUploader } from '../../hooks/use_attachment_uploader'
|
|
18
19
|
import {
|
|
19
20
|
DenormalizedAttachmentResourceForCreate,
|
|
@@ -22,6 +23,8 @@ import {
|
|
|
22
23
|
import { MessageFormAttachmentImage } from './message_form/message_form_attachment_image'
|
|
23
24
|
import { useMessageCreateOrUpdate } from '../../hooks/use_message_create_or_update'
|
|
24
25
|
import { useBroadcastTypingStatus } from '../../hooks/use_broadcast_typing_status'
|
|
26
|
+
import { tokens } from '../../vendor/tapestry/tokens'
|
|
27
|
+
import LinearGradient from 'react-native-linear-gradient'
|
|
25
28
|
|
|
26
29
|
export const MessageForm = {
|
|
27
30
|
Root: MessageFormRoot,
|
|
@@ -216,6 +219,7 @@ function MessageFormAttachments() {
|
|
|
216
219
|
|
|
217
220
|
function MessageFormInput() {
|
|
218
221
|
const styles = useMessageFormStyles()
|
|
222
|
+
const theme = useTheme()
|
|
219
223
|
const { text, setText, onSubmit, usingGiphy, attachmentUploader } =
|
|
220
224
|
React.useContext(MessageFormContext)
|
|
221
225
|
const attachmentError = attachmentUploader?.errorMessage
|
|
@@ -247,6 +251,7 @@ function MessageFormInput() {
|
|
|
247
251
|
multiline={true}
|
|
248
252
|
aria-disabled={true}
|
|
249
253
|
placeholder="Send a message"
|
|
254
|
+
placeholderTextColor={theme.colors.textColorDefaultPlaceholder}
|
|
250
255
|
onChangeText={handleTextChange}
|
|
251
256
|
value={text}
|
|
252
257
|
maxLength={usingGiphy ? GIPHY_MAX_LENGTH : MAX_MESSAGE_LENGTH}
|
|
@@ -260,19 +265,50 @@ function MessageFormInput() {
|
|
|
260
265
|
}
|
|
261
266
|
|
|
262
267
|
function MessageFormSubmitBtn() {
|
|
263
|
-
const styles = useMessageFormStyles()
|
|
264
268
|
const { onSubmit, disabled, usingGiphy } = React.useContext(MessageFormContext)
|
|
269
|
+
const styles = useMessageFormStyles()
|
|
270
|
+
const { colors } = useTheme()
|
|
271
|
+
|
|
272
|
+
const colorKey = disabled ? 'disabled' : 'interaction'
|
|
273
|
+
const interactionStart = colors.buttonStart || colors.interaction
|
|
274
|
+
const interactionEnd = colors.buttonEnd || colors.interaction
|
|
275
|
+
const colorMap = {
|
|
276
|
+
disabled: [
|
|
277
|
+
colors.fillColorButtonNeutralSolidDisabled,
|
|
278
|
+
colors.fillColorButtonNeutralSolidDisabled,
|
|
279
|
+
],
|
|
280
|
+
interaction: [interactionStart, interactionEnd],
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const androidRippleColor = useCreateAndroidRippleColor({ color: colorMap[colorKey][0] })
|
|
284
|
+
const gradientColors = colorMap[colorKey] as [string, string]
|
|
285
|
+
const iconStyles = [styles.submitIcon, disabled && styles.submitIconDisabled]
|
|
265
286
|
|
|
266
287
|
return (
|
|
267
|
-
<
|
|
288
|
+
<Pressable
|
|
268
289
|
disabled={disabled}
|
|
269
|
-
accessibilityLabel={usingGiphy ? 'Search Giphy' : 'Send message'}
|
|
270
|
-
size="md"
|
|
271
|
-
appearance="neutral"
|
|
272
|
-
style={styles.textInputSend}
|
|
273
|
-
name={usingGiphy ? 'general.search' : 'general.upArrow'}
|
|
274
290
|
onPress={onSubmit}
|
|
275
|
-
|
|
291
|
+
accessibilityRole="button"
|
|
292
|
+
accessibilityLabel={usingGiphy ? 'Search Giphy' : 'Send message'}
|
|
293
|
+
style={({ pressed }) => [
|
|
294
|
+
styles.submitPressableWrapper,
|
|
295
|
+
pressed && platformPressedOpacityStyle,
|
|
296
|
+
]}
|
|
297
|
+
android_ripple={{ color: androidRippleColor, borderless: false, foreground: true }}
|
|
298
|
+
>
|
|
299
|
+
<LinearGradient
|
|
300
|
+
start={{ x: 0.1, y: 0.1 }}
|
|
301
|
+
end={{ x: 0.9, y: 0.9 }}
|
|
302
|
+
colors={gradientColors}
|
|
303
|
+
style={styles.submitGradientWrapper}
|
|
304
|
+
>
|
|
305
|
+
<Icon
|
|
306
|
+
name={usingGiphy ? 'general.search' : 'general.upArrow'}
|
|
307
|
+
style={iconStyles}
|
|
308
|
+
accessibilityElementsHidden={true}
|
|
309
|
+
/>
|
|
310
|
+
</LinearGradient>
|
|
311
|
+
</Pressable>
|
|
276
312
|
)
|
|
277
313
|
}
|
|
278
314
|
|
|
@@ -326,31 +362,35 @@ function MessageFormAttachmentPicker() {
|
|
|
326
362
|
}
|
|
327
363
|
|
|
328
364
|
return (
|
|
329
|
-
// TODO: Design Pass
|
|
330
365
|
<View style={styles.attachmentPicker}>
|
|
331
366
|
{isOpen && (
|
|
332
|
-
<View style={styles.
|
|
367
|
+
<View style={styles.attachmentPickerButtonsContainer}>
|
|
333
368
|
<IconButton
|
|
334
369
|
accessibilityLabel="Take a photo"
|
|
335
|
-
|
|
370
|
+
accessibilityHint="Opens your camera"
|
|
371
|
+
size="lg"
|
|
336
372
|
appearance="neutral"
|
|
337
|
-
name=
|
|
373
|
+
name="general.videoCamera"
|
|
338
374
|
onPress={openCamera}
|
|
375
|
+
style={styles.attachmentPickerButton}
|
|
339
376
|
/>
|
|
340
377
|
<IconButton
|
|
341
378
|
accessibilityLabel="Choose a photo"
|
|
342
|
-
|
|
379
|
+
accessibilityHint="Opens your photo gallery"
|
|
380
|
+
size="lg"
|
|
343
381
|
appearance="neutral"
|
|
344
|
-
name=
|
|
382
|
+
name="churchCenter.photosIos"
|
|
345
383
|
onPress={pickImage}
|
|
384
|
+
style={styles.attachmentPickerButton}
|
|
346
385
|
/>
|
|
347
386
|
</View>
|
|
348
387
|
)}
|
|
349
388
|
<IconButton
|
|
350
389
|
accessibilityLabel="File Menu"
|
|
351
|
-
|
|
390
|
+
accessibilityHint="Opens options to attach or take a photo"
|
|
391
|
+
size="lg"
|
|
352
392
|
appearance="neutral"
|
|
353
|
-
name=
|
|
393
|
+
name="general.paperclip"
|
|
354
394
|
onPress={() => setIsOpen(!isOpen)}
|
|
355
395
|
style={styles.formButton}
|
|
356
396
|
/>
|
|
@@ -382,7 +422,7 @@ function MessageFormCommands() {
|
|
|
382
422
|
return (
|
|
383
423
|
<IconButton
|
|
384
424
|
accessibilityLabel="Search Giphy"
|
|
385
|
-
size="
|
|
425
|
+
size="lg"
|
|
386
426
|
appearance="neutral"
|
|
387
427
|
name={'general.bolt'}
|
|
388
428
|
onPress={() => setUsingGiphy(true)}
|
|
@@ -416,7 +456,7 @@ function EditingIndicator() {
|
|
|
416
456
|
const useMessageFormStyles = () => {
|
|
417
457
|
const theme = useTheme()
|
|
418
458
|
const navigationTheme = useNavigationTheme()
|
|
419
|
-
const buttonSize =
|
|
459
|
+
const buttonSize = 38
|
|
420
460
|
|
|
421
461
|
return StyleSheet.create({
|
|
422
462
|
container: {
|
|
@@ -428,7 +468,7 @@ const useMessageFormStyles = () => {
|
|
|
428
468
|
backgroundColor: navigationTheme.colors.card,
|
|
429
469
|
flexDirection: 'row',
|
|
430
470
|
alignItems: 'flex-end',
|
|
431
|
-
gap:
|
|
471
|
+
gap: 16,
|
|
432
472
|
},
|
|
433
473
|
textInputBoundary: {
|
|
434
474
|
borderRadius: 24,
|
|
@@ -444,7 +484,7 @@ const useMessageFormStyles = () => {
|
|
|
444
484
|
},
|
|
445
485
|
textInput: {
|
|
446
486
|
paddingVertical: 8,
|
|
447
|
-
paddingHorizontal:
|
|
487
|
+
paddingHorizontal: 16,
|
|
448
488
|
color: theme.colors.textColorDefaultPrimary,
|
|
449
489
|
textAlignVertical: 'center',
|
|
450
490
|
justifyContent: 'center',
|
|
@@ -469,20 +509,48 @@ const useMessageFormStyles = () => {
|
|
|
469
509
|
formButton: {
|
|
470
510
|
height: buttonSize,
|
|
471
511
|
},
|
|
472
|
-
|
|
473
|
-
borderRadius:
|
|
512
|
+
submitPressableWrapper: {
|
|
513
|
+
borderRadius: buttonSize,
|
|
514
|
+
overflow: 'hidden',
|
|
515
|
+
},
|
|
516
|
+
submitGradientWrapper: {
|
|
517
|
+
flexDirection: 'row',
|
|
518
|
+
justifyContent: 'center',
|
|
519
|
+
alignItems: 'center',
|
|
520
|
+
borderRadius: buttonSize,
|
|
474
521
|
height: buttonSize,
|
|
475
522
|
width: buttonSize,
|
|
476
523
|
},
|
|
524
|
+
submitIcon: {
|
|
525
|
+
fontSize: 16,
|
|
526
|
+
color: tokens.colorNeutral100White,
|
|
527
|
+
},
|
|
528
|
+
submitIconDisabled: {
|
|
529
|
+
color: theme.colors.iconColorDefaultDisabled,
|
|
530
|
+
},
|
|
477
531
|
attachmentPicker: {
|
|
478
532
|
position: 'relative',
|
|
479
533
|
},
|
|
480
|
-
|
|
534
|
+
attachmentPickerButtonsContainer: {
|
|
481
535
|
position: 'absolute',
|
|
482
536
|
left: 0,
|
|
483
537
|
bottom: 40,
|
|
484
538
|
zIndex: 10,
|
|
485
|
-
gap:
|
|
539
|
+
gap: 12,
|
|
540
|
+
},
|
|
541
|
+
attachmentPickerButton: {
|
|
542
|
+
backgroundColor: theme.colors.fillColorNeutral070,
|
|
543
|
+
borderRadius: 20,
|
|
544
|
+
height: buttonSize,
|
|
545
|
+
width: buttonSize,
|
|
546
|
+
elevation: 3,
|
|
547
|
+
...Platform.select({
|
|
548
|
+
ios: {
|
|
549
|
+
borderWidth: 1,
|
|
550
|
+
borderColor: theme.colors.borderColorDefaultBase,
|
|
551
|
+
},
|
|
552
|
+
default: null,
|
|
553
|
+
}),
|
|
486
554
|
},
|
|
487
555
|
messageFormAttachments: {
|
|
488
556
|
flexDirection: 'row',
|