@planningcenter/chat-react-native 3.32.1-rc.0 → 3.33.0-rc.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/message_form.d.ts.map +1 -1
- package/build/components/conversation/message_form.js +22 -1
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/components/display/emoji_avatar.d.ts.map +1 -1
- package/build/components/display/emoji_avatar.js +2 -0
- package/build/components/display/emoji_avatar.js.map +1 -1
- package/build/components/display/icon_avatar.d.ts.map +1 -1
- package/build/components/display/icon_avatar.js +2 -0
- package/build/components/display/icon_avatar.js.map +1 -1
- package/build/components/display/utils/avatar_gradient_colors.d.ts +3 -0
- package/build/components/display/utils/avatar_gradient_colors.d.ts.map +1 -1
- package/build/components/display/utils/avatar_gradient_colors.js +8 -3
- package/build/components/display/utils/avatar_gradient_colors.js.map +1 -1
- package/build/components/page/error_boundary.d.ts.map +1 -1
- package/build/components/page/error_boundary.js +13 -10
- package/build/components/page/error_boundary.js.map +1 -1
- package/build/components/primitive/avatar_primitive.d.ts +3 -1
- package/build/components/primitive/avatar_primitive.d.ts.map +1 -1
- package/build/components/primitive/avatar_primitive.js +10 -2
- package/build/components/primitive/avatar_primitive.js.map +1 -1
- package/build/contexts/api_provider.d.ts.map +1 -1
- package/build/contexts/api_provider.js +2 -0
- package/build/contexts/api_provider.js.map +1 -1
- package/build/hooks/attachments/fallback_chat_configuration.d.ts +4 -0
- package/build/hooks/attachments/fallback_chat_configuration.d.ts.map +1 -0
- package/build/hooks/attachments/fallback_chat_configuration.js +59 -0
- package/build/hooks/attachments/fallback_chat_configuration.js.map +1 -0
- package/build/hooks/groups/use_groups_conversation_create.d.ts.map +1 -1
- package/build/hooks/groups/use_groups_conversation_create.js +1 -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 +43 -11
- 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 +5 -5
- package/build/hooks/services/use_find_or_create_services_conversation.js.map +1 -1
- package/build/hooks/use_attachment_uploader.d.ts.map +1 -1
- package/build/hooks/use_attachment_uploader.js +39 -14
- package/build/hooks/use_attachment_uploader.js.map +1 -1
- package/build/hooks/use_chat_configuration.d.ts +6 -0
- package/build/hooks/use_chat_configuration.d.ts.map +1 -0
- package/build/hooks/use_chat_configuration.js +41 -0
- package/build/hooks/use_chat_configuration.js.map +1 -0
- package/build/hooks/use_conversation_avatar_update.d.ts +26 -0
- package/build/hooks/use_conversation_avatar_update.d.ts.map +1 -0
- package/build/hooks/use_conversation_avatar_update.js +130 -0
- package/build/hooks/use_conversation_avatar_update.js.map +1 -0
- package/build/hooks/use_features.d.ts +1 -0
- package/build/hooks/use_features.d.ts.map +1 -1
- package/build/hooks/use_features.js +1 -0
- package/build/hooks/use_features.js.map +1 -1
- package/build/navigation/index.d.ts +16 -0
- package/build/navigation/index.d.ts.map +1 -1
- package/build/navigation/index.js +9 -0
- package/build/navigation/index.js.map +1 -1
- package/build/screens/avatar_picker/avatar_picker_screen.d.ts +12 -0
- package/build/screens/avatar_picker/avatar_picker_screen.d.ts.map +1 -0
- package/build/screens/avatar_picker/avatar_picker_screen.js +193 -0
- package/build/screens/avatar_picker/avatar_picker_screen.js.map +1 -0
- package/build/screens/avatar_picker/avatar_picker_state.d.ts +38 -0
- package/build/screens/avatar_picker/avatar_picker_state.d.ts.map +1 -0
- package/build/screens/avatar_picker/avatar_picker_state.js +101 -0
- package/build/screens/avatar_picker/avatar_picker_state.js.map +1 -0
- package/build/screens/avatar_picker/avatar_preview.d.ts +9 -0
- package/build/screens/avatar_picker/avatar_preview.d.ts.map +1 -0
- package/build/screens/avatar_picker/avatar_preview.js +39 -0
- package/build/screens/avatar_picker/avatar_preview.js.map +1 -0
- package/build/screens/avatar_picker/color_picker.d.ts +9 -0
- package/build/screens/avatar_picker/color_picker.d.ts.map +1 -0
- package/build/screens/avatar_picker/color_picker.js +53 -0
- package/build/screens/avatar_picker/color_picker.js.map +1 -0
- package/build/screens/avatar_picker/constants.d.ts +3 -0
- package/build/screens/avatar_picker/constants.d.ts.map +1 -0
- package/build/screens/avatar_picker/constants.js +53 -0
- package/build/screens/avatar_picker/constants.js.map +1 -0
- package/build/screens/avatar_picker/emoji_tab.d.ts +7 -0
- package/build/screens/avatar_picker/emoji_tab.d.ts.map +1 -0
- package/build/screens/avatar_picker/emoji_tab.js +55 -0
- package/build/screens/avatar_picker/emoji_tab.js.map +1 -0
- package/build/screens/avatar_picker/icon_grid.d.ts +8 -0
- package/build/screens/avatar_picker/icon_grid.d.ts.map +1 -0
- package/build/screens/avatar_picker/icon_grid.js +48 -0
- package/build/screens/avatar_picker/icon_grid.js.map +1 -0
- package/build/screens/avatar_picker/upload_tab.d.ts +9 -0
- package/build/screens/avatar_picker/upload_tab.d.ts.map +1 -0
- package/build/screens/avatar_picker/upload_tab.js +39 -0
- package/build/screens/avatar_picker/upload_tab.js.map +1 -0
- package/build/screens/conversation_details_screen.d.ts.map +1 -1
- package/build/screens/conversation_details_screen.js +37 -1
- package/build/screens/conversation_details_screen.js.map +1 -1
- package/build/screens/conversation_new/components/avatar_selection_row.d.ts +12 -0
- package/build/screens/conversation_new/components/avatar_selection_row.d.ts.map +1 -0
- package/build/screens/conversation_new/components/avatar_selection_row.js +60 -0
- package/build/screens/conversation_new/components/avatar_selection_row.js.map +1 -0
- package/build/screens/conversation_new/components/gender_filter_toggle.d.ts.map +1 -1
- package/build/screens/conversation_new/components/gender_filter_toggle.js +3 -9
- package/build/screens/conversation_new/components/gender_filter_toggle.js.map +1 -1
- package/build/screens/conversation_new/components/groups_form.d.ts +3 -1
- package/build/screens/conversation_new/components/groups_form.d.ts.map +1 -1
- package/build/screens/conversation_new/components/groups_form.js +22 -8
- 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 +22 -8
- 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 +3 -3
- package/build/screens/conversation_new/conversation_new_screen.js.map +1 -1
- package/build/screens/team_conversation_screen.d.ts.map +1 -1
- package/build/screens/team_conversation_screen.js +1 -1
- package/build/screens/team_conversation_screen.js.map +1 -1
- package/build/types/resources/chat_configuration_resource.d.ts +8 -0
- package/build/types/resources/chat_configuration_resource.d.ts.map +1 -0
- package/build/types/resources/chat_configuration_resource.js +2 -0
- package/build/types/resources/chat_configuration_resource.js.map +1 -0
- package/build/utils/auth_events.d.ts +7 -0
- package/build/utils/auth_events.d.ts.map +1 -0
- package/build/utils/auth_events.js +17 -0
- package/build/utils/auth_events.js.map +1 -0
- package/build/utils/native_adapters/configuration.d.ts +3 -0
- package/build/utils/native_adapters/configuration.d.ts.map +1 -1
- package/build/utils/native_adapters/configuration.js +8 -0
- package/build/utils/native_adapters/configuration.js.map +1 -1
- package/build/utils/native_adapters/document_picker.d.ts +21 -0
- package/build/utils/native_adapters/document_picker.d.ts.map +1 -0
- package/build/utils/native_adapters/document_picker.js +7 -0
- package/build/utils/native_adapters/document_picker.js.map +1 -0
- package/build/utils/native_adapters/image_picker.d.ts +7 -1
- package/build/utils/native_adapters/image_picker.d.ts.map +1 -1
- package/build/utils/native_adapters/image_picker.js.map +1 -1
- package/build/utils/native_adapters/index.d.ts +1 -0
- package/build/utils/native_adapters/index.d.ts.map +1 -1
- package/build/utils/native_adapters/index.js +1 -0
- package/build/utils/native_adapters/index.js.map +1 -1
- package/build/utils/request/get_chat_configuration.d.ts +10 -0
- package/build/utils/request/get_chat_configuration.d.ts.map +1 -0
- package/build/utils/request/get_chat_configuration.js +21 -0
- package/build/utils/request/get_chat_configuration.js.map +1 -0
- package/package.json +4 -3
- package/src/__tests__/hooks/use_attachment_uploader.test.tsx +219 -0
- package/src/__tests__/hooks/use_chat_configuration.test.tsx +80 -0
- package/src/__tests__/utils/native_adapters/configuration.ts +25 -1
- package/src/components/conversation/message_form.tsx +39 -1
- package/src/components/display/emoji_avatar.tsx +7 -2
- package/src/components/display/icon_avatar.tsx +7 -2
- package/src/components/display/utils/avatar_gradient_colors.ts +10 -3
- package/src/components/page/error_boundary.tsx +16 -9
- package/src/components/primitive/avatar_primitive.tsx +11 -2
- package/src/contexts/api_provider.tsx +3 -0
- package/src/hooks/attachments/fallback_chat_configuration.ts +61 -0
- package/src/hooks/groups/use_groups_conversation_create.ts +2 -1
- package/src/hooks/services/use_find_or_create_services_conversation.ts +7 -7
- package/src/hooks/use_attachment_uploader.ts +39 -15
- package/src/hooks/use_chat_configuration.ts +54 -0
- package/src/hooks/use_conversation_avatar_update.ts +163 -0
- package/src/hooks/use_features.ts +1 -0
- package/src/navigation/index.tsx +13 -0
- package/src/screens/avatar_picker/__tests__/avatar_picker_state.test.ts +157 -0
- package/src/screens/avatar_picker/avatar_picker_screen.tsx +312 -0
- package/src/screens/avatar_picker/avatar_picker_state.ts +141 -0
- package/src/screens/avatar_picker/avatar_preview.tsx +46 -0
- package/src/screens/avatar_picker/color_picker.tsx +91 -0
- package/src/screens/avatar_picker/constants.ts +53 -0
- package/src/screens/avatar_picker/emoji_tab.tsx +76 -0
- package/src/screens/avatar_picker/icon_grid.tsx +81 -0
- package/src/screens/avatar_picker/upload_tab.tsx +62 -0
- package/src/screens/conversation_details_screen.tsx +60 -1
- package/src/screens/conversation_new/components/avatar_selection_row.tsx +82 -0
- package/src/screens/conversation_new/components/gender_filter_toggle.tsx +3 -9
- package/src/screens/conversation_new/components/groups_form.tsx +33 -6
- package/src/screens/conversation_new/components/services_form.tsx +37 -6
- package/src/screens/conversation_new/conversation_new_screen.tsx +17 -3
- package/src/screens/team_conversation_screen.tsx +2 -1
- package/src/types/resources/chat_configuration_resource.ts +11 -0
- package/src/utils/auth_events.ts +21 -0
- package/src/utils/native_adapters/configuration.ts +10 -0
- package/src/utils/native_adapters/document_picker.ts +26 -0
- package/src/utils/native_adapters/image_picker.ts +8 -1
- package/src/utils/native_adapters/index.ts +1 -0
- package/src/utils/request/get_chat_configuration.ts +23 -0
- package/build/hooks/attachments/supported_extensions.d.ts +0 -2
- package/build/hooks/attachments/supported_extensions.d.ts.map +0 -1
- package/build/hooks/attachments/supported_extensions.js +0 -48
- package/build/hooks/attachments/supported_extensions.js.map +0 -1
- package/src/hooks/attachments/supported_extensions.ts +0 -47
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { PlatformPressable } from '@react-navigation/elements';
|
|
2
|
+
import React, { useCallback } from 'react';
|
|
3
|
+
import { FlatList, StyleSheet, useWindowDimensions } from 'react-native';
|
|
4
|
+
import LinearGradient from 'react-native-linear-gradient';
|
|
5
|
+
import { COLOR_KEYS, getAvatarGradientProps, } from '../../components/display/utils/avatar_gradient_colors';
|
|
6
|
+
import { useTheme } from '../../hooks';
|
|
7
|
+
import { GRID_COLUMNS } from './constants';
|
|
8
|
+
export function ColorPicker({ selectedColor, onColorSelect }) {
|
|
9
|
+
const styles = useStyles();
|
|
10
|
+
const renderItem = useCallback(({ item }) => {
|
|
11
|
+
const gradientProps = getAvatarGradientProps(item);
|
|
12
|
+
const isSelected = item === selectedColor;
|
|
13
|
+
return (<PlatformPressable onPress={() => onColorSelect(item)} style={[styles.swatchOuter, isSelected && styles.swatchSelected]} accessibilityRole="button" accessibilityLabel={`${item.replace(/-/g, ' ')} color`} accessibilityState={{ selected: isSelected }}>
|
|
14
|
+
<LinearGradient {...gradientProps} style={styles.swatch}/>
|
|
15
|
+
</PlatformPressable>);
|
|
16
|
+
}, [selectedColor, onColorSelect, styles.swatch, styles.swatchOuter, styles.swatchSelected]);
|
|
17
|
+
return (<FlatList data={COLOR_KEYS} numColumns={GRID_COLUMNS} keyExtractor={item => item} renderItem={renderItem} contentContainerStyle={styles.grid} columnWrapperStyle={styles.row} scrollEnabled={false}/>);
|
|
18
|
+
}
|
|
19
|
+
const PADDING = 16;
|
|
20
|
+
const GAP = 8;
|
|
21
|
+
const useStyles = () => {
|
|
22
|
+
const { colors } = useTheme();
|
|
23
|
+
const { width: screenWidth } = useWindowDimensions();
|
|
24
|
+
const swatchSize = Math.floor((screenWidth - PADDING * 2 - (GRID_COLUMNS - 1) * GAP) / GRID_COLUMNS);
|
|
25
|
+
const innerSize = swatchSize - 6;
|
|
26
|
+
return StyleSheet.create({
|
|
27
|
+
grid: {
|
|
28
|
+
paddingHorizontal: PADDING,
|
|
29
|
+
paddingVertical: 12,
|
|
30
|
+
},
|
|
31
|
+
row: {
|
|
32
|
+
gap: GAP,
|
|
33
|
+
marginBottom: GAP,
|
|
34
|
+
},
|
|
35
|
+
swatchOuter: {
|
|
36
|
+
width: swatchSize,
|
|
37
|
+
height: swatchSize,
|
|
38
|
+
borderRadius: swatchSize / 2,
|
|
39
|
+
alignItems: 'center',
|
|
40
|
+
justifyContent: 'center',
|
|
41
|
+
},
|
|
42
|
+
swatchSelected: {
|
|
43
|
+
borderWidth: 3,
|
|
44
|
+
borderColor: colors.interaction,
|
|
45
|
+
},
|
|
46
|
+
swatch: {
|
|
47
|
+
width: innerSize,
|
|
48
|
+
height: innerSize,
|
|
49
|
+
borderRadius: innerSize / 2,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=color_picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color_picker.js","sourceRoot":"","sources":["../../../src/screens/avatar_picker/color_picker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACxE,OAAO,cAAc,MAAM,8BAA8B,CAAA;AACzD,OAAO,EACL,UAAU,EAEV,sBAAsB,GACvB,MAAM,uDAAuD,CAAA;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAO1C,MAAM,UAAU,WAAW,CAAC,EAAE,aAAa,EAAE,aAAa,EAAoB;IAC5E,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAE1B,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,EAAE,IAAI,EAAkC,EAAE,EAAE;QAC3C,MAAM,aAAa,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;QAClD,MAAM,UAAU,GAAG,IAAI,KAAK,aAAa,CAAA;QAEzC,OAAO,CACL,CAAC,iBAAiB,CAChB,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CACnC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,IAAI,MAAM,CAAC,cAAc,CAAC,CAAC,CACjE,iBAAiB,CAAC,QAAQ,CAC1B,kBAAkB,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,CACvD,kBAAkB,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAE7C;UAAA,CAAC,cAAc,CAAC,IAAI,aAAa,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAC1D;QAAA,EAAE,iBAAiB,CAAC,CACrB,CAAA;IACH,CAAC,EACD,CAAC,aAAa,EAAE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,cAAc,CAAC,CACzF,CAAA;IAED,OAAO,CACL,CAAC,QAAQ,CACP,IAAI,CAAC,CAAC,UAAU,CAAC,CACjB,UAAU,CAAC,CAAC,YAAY,CAAC,CACzB,YAAY,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAC3B,UAAU,CAAC,CAAC,UAAU,CAAC,CACvB,qBAAqB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CACnC,kBAAkB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAC/B,aAAa,CAAC,CAAC,KAAK,CAAC,EACrB,CACH,CAAA;AACH,CAAC;AAED,MAAM,OAAO,GAAG,EAAE,CAAA;AAClB,MAAM,GAAG,GAAG,CAAC,CAAA;AAEb,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAC7B,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,mBAAmB,EAAE,CAAA;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAC3B,CAAC,WAAW,GAAG,OAAO,GAAG,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,YAAY,CACtE,CAAA;IACD,MAAM,SAAS,GAAG,UAAU,GAAG,CAAC,CAAA;IAEhC,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,IAAI,EAAE;YACJ,iBAAiB,EAAE,OAAO;YAC1B,eAAe,EAAE,EAAE;SACpB;QACD,GAAG,EAAE;YACH,GAAG,EAAE,GAAG;YACR,YAAY,EAAE,GAAG;SAClB;QACD,WAAW,EAAE;YACX,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,UAAU;YAClB,YAAY,EAAE,UAAU,GAAG,CAAC;YAC5B,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,QAAQ;SACzB;QACD,cAAc,EAAE;YACd,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC;QACD,MAAM,EAAE;YACN,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,SAAS;YACjB,YAAY,EAAE,SAAS,GAAG,CAAC;SAC5B;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import { PlatformPressable } from '@react-navigation/elements'\nimport React, { useCallback } from 'react'\nimport { FlatList, StyleSheet, useWindowDimensions } from 'react-native'\nimport LinearGradient from 'react-native-linear-gradient'\nimport {\n COLOR_KEYS,\n type CustomAvatarColorKey,\n getAvatarGradientProps,\n} from '../../components/display/utils/avatar_gradient_colors'\nimport { useTheme } from '../../hooks'\nimport { GRID_COLUMNS } from './constants'\n\ninterface ColorPickerProps {\n selectedColor: string\n onColorSelect: (color: CustomAvatarColorKey) => void\n}\n\nexport function ColorPicker({ selectedColor, onColorSelect }: ColorPickerProps) {\n const styles = useStyles()\n\n const renderItem = useCallback(\n ({ item }: { item: CustomAvatarColorKey }) => {\n const gradientProps = getAvatarGradientProps(item)\n const isSelected = item === selectedColor\n\n return (\n <PlatformPressable\n onPress={() => onColorSelect(item)}\n style={[styles.swatchOuter, isSelected && styles.swatchSelected]}\n accessibilityRole=\"button\"\n accessibilityLabel={`${item.replace(/-/g, ' ')} color`}\n accessibilityState={{ selected: isSelected }}\n >\n <LinearGradient {...gradientProps} style={styles.swatch} />\n </PlatformPressable>\n )\n },\n [selectedColor, onColorSelect, styles.swatch, styles.swatchOuter, styles.swatchSelected]\n )\n\n return (\n <FlatList\n data={COLOR_KEYS}\n numColumns={GRID_COLUMNS}\n keyExtractor={item => item}\n renderItem={renderItem}\n contentContainerStyle={styles.grid}\n columnWrapperStyle={styles.row}\n scrollEnabled={false}\n />\n )\n}\n\nconst PADDING = 16\nconst GAP = 8\n\nconst useStyles = () => {\n const { colors } = useTheme()\n const { width: screenWidth } = useWindowDimensions()\n const swatchSize = Math.floor(\n (screenWidth - PADDING * 2 - (GRID_COLUMNS - 1) * GAP) / GRID_COLUMNS\n )\n const innerSize = swatchSize - 6\n\n return StyleSheet.create({\n grid: {\n paddingHorizontal: PADDING,\n paddingVertical: 12,\n },\n row: {\n gap: GAP,\n marginBottom: GAP,\n },\n swatchOuter: {\n width: swatchSize,\n height: swatchSize,\n borderRadius: swatchSize / 2,\n alignItems: 'center',\n justifyContent: 'center',\n },\n swatchSelected: {\n borderWidth: 3,\n borderColor: colors.interaction,\n },\n swatch: {\n width: innerSize,\n height: innerSize,\n borderRadius: innerSize / 2,\n },\n })\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/screens/avatar_picker/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAE,MAAM,EAkDpC,CAAA;AAED,eAAO,MAAM,YAAY,IAAI,CAAA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export const AVATAR_ICON_KEYS = [
|
|
2
|
+
// Church
|
|
3
|
+
'book-bible',
|
|
4
|
+
'church',
|
|
5
|
+
'cross',
|
|
6
|
+
'dove',
|
|
7
|
+
'hands-heart',
|
|
8
|
+
'person-rays',
|
|
9
|
+
'praying-hands',
|
|
10
|
+
'podium',
|
|
11
|
+
'droplet',
|
|
12
|
+
'person-drowning',
|
|
13
|
+
'lighthouse',
|
|
14
|
+
// Services
|
|
15
|
+
'guitar',
|
|
16
|
+
'guitar-electric',
|
|
17
|
+
'violin',
|
|
18
|
+
'calendar-heart',
|
|
19
|
+
'hand-heart',
|
|
20
|
+
'hand-wave',
|
|
21
|
+
'baby',
|
|
22
|
+
'children',
|
|
23
|
+
'mug-hot',
|
|
24
|
+
'video-camera',
|
|
25
|
+
'music',
|
|
26
|
+
'piano-keyboard',
|
|
27
|
+
'drum',
|
|
28
|
+
'user-graduate',
|
|
29
|
+
'comments-question',
|
|
30
|
+
'presentation',
|
|
31
|
+
'microphone-stand',
|
|
32
|
+
'id-badge',
|
|
33
|
+
'book-user',
|
|
34
|
+
'hand-holding-heart',
|
|
35
|
+
'guitars',
|
|
36
|
+
'amp-guitar',
|
|
37
|
+
'school-flag',
|
|
38
|
+
'shield-check',
|
|
39
|
+
'projector',
|
|
40
|
+
// Groups
|
|
41
|
+
'people',
|
|
42
|
+
'people-group',
|
|
43
|
+
'person-dress',
|
|
44
|
+
'person',
|
|
45
|
+
'seedling',
|
|
46
|
+
'comments-alt',
|
|
47
|
+
'globe',
|
|
48
|
+
'book-open-reader',
|
|
49
|
+
'running',
|
|
50
|
+
'leaf',
|
|
51
|
+
];
|
|
52
|
+
export const GRID_COLUMNS = 6;
|
|
53
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/screens/avatar_picker/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAa;IACxC,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,OAAO;IACP,MAAM;IACN,aAAa;IACb,aAAa;IACb,eAAe;IACf,QAAQ;IACR,SAAS;IACT,iBAAiB;IACjB,YAAY;IACZ,WAAW;IACX,QAAQ;IACR,iBAAiB;IACjB,QAAQ;IACR,gBAAgB;IAChB,YAAY;IACZ,WAAW;IACX,MAAM;IACN,UAAU;IACV,SAAS;IACT,cAAc;IACd,OAAO;IACP,gBAAgB;IAChB,MAAM;IACN,eAAe;IACf,mBAAmB;IACnB,cAAc;IACd,kBAAkB;IAClB,UAAU;IACV,WAAW;IACX,oBAAoB;IACpB,SAAS;IACT,YAAY;IACZ,aAAa;IACb,cAAc;IACd,WAAW;IACX,SAAS;IACT,QAAQ;IACR,cAAc;IACd,cAAc;IACd,QAAQ;IACR,UAAU;IACV,cAAc;IACd,OAAO;IACP,kBAAkB;IAClB,SAAS;IACT,MAAM;CACP,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAA","sourcesContent":["export const AVATAR_ICON_KEYS: string[] = [\n // Church\n 'book-bible',\n 'church',\n 'cross',\n 'dove',\n 'hands-heart',\n 'person-rays',\n 'praying-hands',\n 'podium',\n 'droplet',\n 'person-drowning',\n 'lighthouse',\n // Services\n 'guitar',\n 'guitar-electric',\n 'violin',\n 'calendar-heart',\n 'hand-heart',\n 'hand-wave',\n 'baby',\n 'children',\n 'mug-hot',\n 'video-camera',\n 'music',\n 'piano-keyboard',\n 'drum',\n 'user-graduate',\n 'comments-question',\n 'presentation',\n 'microphone-stand',\n 'id-badge',\n 'book-user',\n 'hand-holding-heart',\n 'guitars',\n 'amp-guitar',\n 'school-flag',\n 'shield-check',\n 'projector',\n // Groups\n 'people',\n 'people-group',\n 'person-dress',\n 'person',\n 'seedling',\n 'comments-alt',\n 'globe',\n 'book-open-reader',\n 'running',\n 'leaf',\n]\n\nexport const GRID_COLUMNS = 6\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emoji_tab.d.ts","sourceRoot":"","sources":["../../../src/screens/avatar_picker/emoji_tab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAA;AAK1C,UAAU,aAAa;IACrB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACvC;AAED,wBAAgB,QAAQ,CAAC,EAAE,aAAa,EAAE,EAAE,aAAa,qBAuDxD"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
|
+
import { EmojiKeyboard } from 'rn-emoji-keyboard';
|
|
4
|
+
import { useTheme } from '../../hooks';
|
|
5
|
+
export function EmojiTab({ onEmojiSelect }) {
|
|
6
|
+
const styles = useStyles();
|
|
7
|
+
const { colors } = useTheme();
|
|
8
|
+
const handleEmojiSelected = useCallback((emojiObject) => {
|
|
9
|
+
onEmojiSelect(emojiObject.emoji);
|
|
10
|
+
}, [onEmojiSelect]);
|
|
11
|
+
const emojiTheme = {
|
|
12
|
+
container: colors.fillColorNeutral100Inverted,
|
|
13
|
+
header: colors.textColorDefaultSecondary,
|
|
14
|
+
knob: colors.fillColorNeutral040,
|
|
15
|
+
skinTonesContainer: colors.fillColorNeutral060,
|
|
16
|
+
category: {
|
|
17
|
+
icon: colors.textColorDefaultSecondary,
|
|
18
|
+
iconActive: colors.interaction,
|
|
19
|
+
container: colors.fillColorNeutral100Inverted,
|
|
20
|
+
containerActive: colors.fillColorNeutral080,
|
|
21
|
+
},
|
|
22
|
+
search: {
|
|
23
|
+
background: colors.fillColorNeutral080,
|
|
24
|
+
text: colors.textColorDefaultPrimary,
|
|
25
|
+
placeholder: colors.textColorDefaultSecondary,
|
|
26
|
+
icon: colors.textColorDefaultSecondary,
|
|
27
|
+
},
|
|
28
|
+
emoji: {
|
|
29
|
+
selected: colors.fillColorNeutral080,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
return (<View style={styles.container}>
|
|
33
|
+
<EmojiKeyboard categoryPosition="top" onEmojiSelected={handleEmojiSelected} enableSearchBar enableRecentlyUsed theme={emojiTheme} styles={{
|
|
34
|
+
container: { borderRadius: 0 },
|
|
35
|
+
category: {
|
|
36
|
+
container: {
|
|
37
|
+
borderRadius: 0,
|
|
38
|
+
marginTop: -6,
|
|
39
|
+
borderBottomWidth: 1,
|
|
40
|
+
borderBottomColor: colors.borderColorDefaultDim,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
}}/>
|
|
44
|
+
</View>);
|
|
45
|
+
}
|
|
46
|
+
const useStyles = () => {
|
|
47
|
+
const { colors } = useTheme();
|
|
48
|
+
return StyleSheet.create({
|
|
49
|
+
container: {
|
|
50
|
+
flex: 1,
|
|
51
|
+
backgroundColor: colors.fillColorNeutral100Inverted,
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=emoji_tab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emoji_tab.js","sourceRoot":"","sources":["../../../src/screens/avatar_picker/emoji_tab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAkB,MAAM,mBAAmB,CAAA;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAMtC,MAAM,UAAU,QAAQ,CAAC,EAAE,aAAa,EAAiB;IACvD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAE7B,MAAM,mBAAmB,GAAG,WAAW,CACrC,CAAC,WAAsB,EAAE,EAAE;QACzB,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAClC,CAAC,EACD,CAAC,aAAa,CAAC,CAChB,CAAA;IAED,MAAM,UAAU,GAAG;QACjB,SAAS,EAAE,MAAM,CAAC,2BAA2B;QAC7C,MAAM,EAAE,MAAM,CAAC,yBAAyB;QACxC,IAAI,EAAE,MAAM,CAAC,mBAAmB;QAChC,kBAAkB,EAAE,MAAM,CAAC,mBAAmB;QAC9C,QAAQ,EAAE;YACR,IAAI,EAAE,MAAM,CAAC,yBAAyB;YACtC,UAAU,EAAE,MAAM,CAAC,WAAW;YAC9B,SAAS,EAAE,MAAM,CAAC,2BAA2B;YAC7C,eAAe,EAAE,MAAM,CAAC,mBAAmB;SAC5C;QACD,MAAM,EAAE;YACN,UAAU,EAAE,MAAM,CAAC,mBAAmB;YACtC,IAAI,EAAE,MAAM,CAAC,uBAAuB;YACpC,WAAW,EAAE,MAAM,CAAC,yBAAyB;YAC7C,IAAI,EAAE,MAAM,CAAC,yBAAyB;SACvC;QACD,KAAK,EAAE;YACL,QAAQ,EAAE,MAAM,CAAC,mBAAmB;SACrC;KACF,CAAA;IAED,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAC5B;MAAA,CAAC,aAAa,CACZ,gBAAgB,CAAC,KAAK,CACtB,eAAe,CAAC,CAAC,mBAAmB,CAAC,CACrC,eAAe,CACf,kBAAkB,CAClB,KAAK,CAAC,CAAC,UAAU,CAAC,CAClB,MAAM,CAAC,CAAC;YACN,SAAS,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE;YAC9B,QAAQ,EAAE;gBACR,SAAS,EAAE;oBACT,YAAY,EAAE,CAAC;oBACf,SAAS,EAAE,CAAC,CAAC;oBACb,iBAAiB,EAAE,CAAC;oBACpB,iBAAiB,EAAE,MAAM,CAAC,qBAAqB;iBAChD;aACF;SACF,CAAC,EAEN;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC;AAED,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAE7B,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,SAAS,EAAE;YACT,IAAI,EAAE,CAAC;YACP,eAAe,EAAE,MAAM,CAAC,2BAA2B;SACpD;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import React, { useCallback } from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport { EmojiKeyboard, type EmojiType } from 'rn-emoji-keyboard'\nimport { useTheme } from '../../hooks'\n\ninterface EmojiTabProps {\n onEmojiSelect: (emoji: string) => void\n}\n\nexport function EmojiTab({ onEmojiSelect }: EmojiTabProps) {\n const styles = useStyles()\n const { colors } = useTheme()\n\n const handleEmojiSelected = useCallback(\n (emojiObject: EmojiType) => {\n onEmojiSelect(emojiObject.emoji)\n },\n [onEmojiSelect]\n )\n\n const emojiTheme = {\n container: colors.fillColorNeutral100Inverted,\n header: colors.textColorDefaultSecondary,\n knob: colors.fillColorNeutral040,\n skinTonesContainer: colors.fillColorNeutral060,\n category: {\n icon: colors.textColorDefaultSecondary,\n iconActive: colors.interaction,\n container: colors.fillColorNeutral100Inverted,\n containerActive: colors.fillColorNeutral080,\n },\n search: {\n background: colors.fillColorNeutral080,\n text: colors.textColorDefaultPrimary,\n placeholder: colors.textColorDefaultSecondary,\n icon: colors.textColorDefaultSecondary,\n },\n emoji: {\n selected: colors.fillColorNeutral080,\n },\n }\n\n return (\n <View style={styles.container}>\n <EmojiKeyboard\n categoryPosition=\"top\"\n onEmojiSelected={handleEmojiSelected}\n enableSearchBar\n enableRecentlyUsed\n theme={emojiTheme}\n styles={{\n container: { borderRadius: 0 },\n category: {\n container: {\n borderRadius: 0,\n marginTop: -6,\n borderBottomWidth: 1,\n borderBottomColor: colors.borderColorDefaultDim,\n },\n },\n }}\n />\n </View>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n\n return StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: colors.fillColorNeutral100Inverted,\n },\n })\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface IconGridProps {
|
|
3
|
+
selectedIconKey: string | null;
|
|
4
|
+
onIconSelect: (iconKey: string) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function IconGrid({ selectedIconKey, onIconSelect }: IconGridProps): React.JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=icon_grid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon_grid.d.ts","sourceRoot":"","sources":["../../../src/screens/avatar_picker/icon_grid.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAsB,MAAM,OAAO,CAAA;AAK1C,UAAU,aAAa;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC;AAED,wBAAgB,QAAQ,CAAC,EAAE,eAAe,EAAE,YAAY,EAAE,EAAE,aAAa,qBAiCxE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
|
|
2
|
+
import { PlatformPressable } from '@react-navigation/elements';
|
|
3
|
+
import React, { useCallback } from 'react';
|
|
4
|
+
import { FlatList, StyleSheet, useWindowDimensions } from 'react-native';
|
|
5
|
+
import { useTheme } from '../../hooks';
|
|
6
|
+
import { AVATAR_ICON_KEYS, GRID_COLUMNS } from './constants';
|
|
7
|
+
export function IconGrid({ selectedIconKey, onIconSelect }) {
|
|
8
|
+
const styles = useStyles();
|
|
9
|
+
const renderItem = useCallback(({ item }) => {
|
|
10
|
+
const isSelected = item === selectedIconKey;
|
|
11
|
+
return (<PlatformPressable onPress={() => onIconSelect(item)} style={[styles.cell, isSelected && styles.cellSelected]} accessibilityRole="button" accessibilityLabel={`${item.replace(/-/g, ' ')} icon`} accessibilityState={{ selected: isSelected }}>
|
|
12
|
+
<FontAwesomeIcon icon={['fas', item]} size={20} color="white"/>
|
|
13
|
+
</PlatformPressable>);
|
|
14
|
+
}, [selectedIconKey, onIconSelect, styles.cell, styles.cellSelected]);
|
|
15
|
+
return (<FlatList data={AVATAR_ICON_KEYS} numColumns={GRID_COLUMNS} keyExtractor={item => item} renderItem={renderItem} contentContainerStyle={styles.grid} columnWrapperStyle={styles.row} style={styles.list}/>);
|
|
16
|
+
}
|
|
17
|
+
const PADDING = 16;
|
|
18
|
+
const GAP = 8;
|
|
19
|
+
const useStyles = () => {
|
|
20
|
+
const { colors } = useTheme();
|
|
21
|
+
const { width: screenWidth } = useWindowDimensions();
|
|
22
|
+
const cellSize = Math.floor((screenWidth - PADDING * 2 - (GRID_COLUMNS - 1) * GAP) / GRID_COLUMNS);
|
|
23
|
+
return StyleSheet.create({
|
|
24
|
+
list: {
|
|
25
|
+
flex: 1,
|
|
26
|
+
},
|
|
27
|
+
grid: {
|
|
28
|
+
padding: PADDING,
|
|
29
|
+
},
|
|
30
|
+
row: {
|
|
31
|
+
gap: GAP,
|
|
32
|
+
marginBottom: GAP,
|
|
33
|
+
},
|
|
34
|
+
cell: {
|
|
35
|
+
width: cellSize,
|
|
36
|
+
height: cellSize,
|
|
37
|
+
borderRadius: cellSize / 2,
|
|
38
|
+
backgroundColor: colors.fillColorNeutral040,
|
|
39
|
+
alignItems: 'center',
|
|
40
|
+
justifyContent: 'center',
|
|
41
|
+
},
|
|
42
|
+
cellSelected: {
|
|
43
|
+
borderWidth: 3,
|
|
44
|
+
borderColor: colors.interaction,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=icon_grid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon_grid.js","sourceRoot":"","sources":["../../../src/screens/avatar_picker/icon_grid.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { IconName } from '@fortawesome/fontawesome-svg-core'\nimport { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome'\nimport { PlatformPressable } from '@react-navigation/elements'\nimport React, { useCallback } from 'react'\nimport { FlatList, StyleSheet, useWindowDimensions } from 'react-native'\nimport { useTheme } from '../../hooks'\nimport { AVATAR_ICON_KEYS, GRID_COLUMNS } from './constants'\n\ninterface IconGridProps {\n selectedIconKey: string | null\n onIconSelect: (iconKey: string) => void\n}\n\nexport function IconGrid({ selectedIconKey, onIconSelect }: IconGridProps) {\n const styles = useStyles()\n\n const renderItem = useCallback(\n ({ item }: { item: string }) => {\n const isSelected = item === selectedIconKey\n\n return (\n <PlatformPressable\n onPress={() => onIconSelect(item)}\n style={[styles.cell, isSelected && styles.cellSelected]}\n accessibilityRole=\"button\"\n accessibilityLabel={`${item.replace(/-/g, ' ')} icon`}\n accessibilityState={{ selected: isSelected }}\n >\n <FontAwesomeIcon icon={['fas', item as IconName]} size={20} color=\"white\" />\n </PlatformPressable>\n )\n },\n [selectedIconKey, onIconSelect, styles.cell, styles.cellSelected]\n )\n\n return (\n <FlatList\n data={AVATAR_ICON_KEYS}\n numColumns={GRID_COLUMNS}\n keyExtractor={item => item}\n renderItem={renderItem}\n contentContainerStyle={styles.grid}\n columnWrapperStyle={styles.row}\n style={styles.list}\n />\n )\n}\n\nconst PADDING = 16\nconst GAP = 8\n\nconst useStyles = () => {\n const { colors } = useTheme()\n const { width: screenWidth } = useWindowDimensions()\n const cellSize = Math.floor((screenWidth - PADDING * 2 - (GRID_COLUMNS - 1) * GAP) / GRID_COLUMNS)\n\n return StyleSheet.create({\n list: {\n flex: 1,\n },\n grid: {\n padding: PADDING,\n },\n row: {\n gap: GAP,\n marginBottom: GAP,\n },\n cell: {\n width: cellSize,\n height: cellSize,\n borderRadius: cellSize / 2,\n backgroundColor: colors.fillColorNeutral040,\n alignItems: 'center',\n justifyContent: 'center',\n },\n cellSelected: {\n borderWidth: 3,\n borderColor: colors.interaction,\n },\n })\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ImagePickerAsset } from '../../utils/native_adapters/image_picker';
|
|
3
|
+
interface UploadTabProps {
|
|
4
|
+
imagePreviewUri: string | null;
|
|
5
|
+
onImageSelect: (asset: ImagePickerAsset) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function UploadTab({ imagePreviewUri, onImageSelect }: UploadTabProps): React.JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=upload_tab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload_tab.d.ts","sourceRoot":"","sources":["../../../src/screens/avatar_picker/upload_tab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAA;AAK1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAA;AAIhF,UAAU,cAAc;IACtB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAA;CACjD;AAED,wBAAgB,SAAS,CAAC,EAAE,eAAe,EAAE,aAAa,EAAE,EAAE,cAAc,qBAkC3E"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { Alert, StyleSheet, View } from 'react-native';
|
|
3
|
+
import { Button } from '../../components';
|
|
4
|
+
import { useTheme } from '../../hooks';
|
|
5
|
+
import { ImagePicker } from '../../utils/native_adapters';
|
|
6
|
+
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
|
|
7
|
+
export function UploadTab({ imagePreviewUri, onImageSelect }) {
|
|
8
|
+
const styles = useStyles();
|
|
9
|
+
const pickImage = useCallback(async () => {
|
|
10
|
+
const result = await ImagePicker.openImageLibraryAsync({
|
|
11
|
+
mediaTypes: ['images'],
|
|
12
|
+
allowsEditing: true,
|
|
13
|
+
allowsMultipleSelection: false,
|
|
14
|
+
});
|
|
15
|
+
if (result.canceled || !result.assets?.[0])
|
|
16
|
+
return;
|
|
17
|
+
const asset = result.assets[0];
|
|
18
|
+
if (asset.fileSize && asset.fileSize > MAX_FILE_SIZE) {
|
|
19
|
+
Alert.alert('Image too large', 'Please choose an image under 10MB.');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
onImageSelect(asset);
|
|
23
|
+
}, [onImageSelect]);
|
|
24
|
+
return (<View style={styles.container}>
|
|
25
|
+
<Button title={imagePreviewUri ? 'Change photo' : 'Choose photo'} iconNameLeft="general.image" onPress={pickImage} variant="outline" appearance="interaction" size="md"/>
|
|
26
|
+
</View>);
|
|
27
|
+
}
|
|
28
|
+
const useStyles = () => {
|
|
29
|
+
const { colors } = useTheme();
|
|
30
|
+
return StyleSheet.create({
|
|
31
|
+
container: {
|
|
32
|
+
flex: 1,
|
|
33
|
+
alignItems: 'center',
|
|
34
|
+
justifyContent: 'center',
|
|
35
|
+
backgroundColor: colors.fillColorNeutral100Inverted,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=upload_tab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload_tab.js","sourceRoot":"","sources":["../../../src/screens/avatar_picker/upload_tab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAGzD,MAAM,aAAa,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA,CAAC,OAAO;AAO9C,MAAM,UAAU,SAAS,CAAC,EAAE,eAAe,EAAE,aAAa,EAAkB;IAC1E,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAE1B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACvC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,qBAAqB,CAAC;YACrD,UAAU,EAAE,CAAC,QAAQ,CAAC;YACtB,aAAa,EAAE,IAAI;YACnB,uBAAuB,EAAE,KAAK;SAC/B,CAAC,CAAA;QAEF,IAAI,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAAE,OAAM;QAElD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QAE9B,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,GAAG,aAAa,EAAE,CAAC;YACrD,KAAK,CAAC,KAAK,CAAC,iBAAiB,EAAE,oCAAoC,CAAC,CAAA;YACpE,OAAM;QACR,CAAC;QAED,aAAa,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAA;IAEnB,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAC5B;MAAA,CAAC,MAAM,CACL,KAAK,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CACzD,YAAY,CAAC,eAAe,CAC5B,OAAO,CAAC,CAAC,SAAS,CAAC,CACnB,OAAO,CAAC,SAAS,CACjB,UAAU,CAAC,aAAa,CACxB,IAAI,CAAC,IAAI,EAEb;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC;AAED,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAE7B,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,SAAS,EAAE;YACT,IAAI,EAAE,CAAC;YACP,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,QAAQ;YACxB,eAAe,EAAE,MAAM,CAAC,2BAA2B;SACpD;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import React, { useCallback } from 'react'\nimport { Alert, StyleSheet, View } from 'react-native'\nimport { Button } from '../../components'\nimport { useTheme } from '../../hooks'\nimport { ImagePicker } from '../../utils/native_adapters'\nimport type { ImagePickerAsset } from '../../utils/native_adapters/image_picker'\n\nconst MAX_FILE_SIZE = 10 * 1024 * 1024 // 10MB\n\ninterface UploadTabProps {\n imagePreviewUri: string | null\n onImageSelect: (asset: ImagePickerAsset) => void\n}\n\nexport function UploadTab({ imagePreviewUri, onImageSelect }: UploadTabProps) {\n const styles = useStyles()\n\n const pickImage = useCallback(async () => {\n const result = await ImagePicker.openImageLibraryAsync({\n mediaTypes: ['images'],\n allowsEditing: true,\n allowsMultipleSelection: false,\n })\n\n if (result.canceled || !result.assets?.[0]) return\n\n const asset = result.assets[0]\n\n if (asset.fileSize && asset.fileSize > MAX_FILE_SIZE) {\n Alert.alert('Image too large', 'Please choose an image under 10MB.')\n return\n }\n\n onImageSelect(asset)\n }, [onImageSelect])\n\n return (\n <View style={styles.container}>\n <Button\n title={imagePreviewUri ? 'Change photo' : 'Choose photo'}\n iconNameLeft=\"general.image\"\n onPress={pickImage}\n variant=\"outline\"\n appearance=\"interaction\"\n size=\"md\"\n />\n </View>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n\n return StyleSheet.create({\n container: {\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: colors.fillColorNeutral100Inverted,\n },\n })\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation_details_screen.d.ts","sourceRoot":"","sources":["../../src/screens/conversation_details_screen.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAgB,iBAAiB,EAAiB,MAAM,0BAA0B,CAAA;AACzF,OAAO,KAQN,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"conversation_details_screen.d.ts","sourceRoot":"","sources":["../../src/screens/conversation_details_screen.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAgB,iBAAiB,EAAiB,MAAM,0BAA0B,CAAA;AACzF,OAAO,KAQN,MAAM,OAAO,CAAA;AA4Ed,MAAM,MAAM,8BAA8B,GAAG,iBAAiB,CAAC;IAC7D,eAAe,EAAE,MAAM,CAAA;CACxB,CAAC,CAAA;AAEF,wBAAgB,yBAAyB,CAAC,EAAE,KAAK,EAAE,EAAE,8BAA8B,qBA+WlF"}
|
|
@@ -2,7 +2,8 @@ import { HeaderTitle as ElementsHeaderTitle, PlatformPressable, } from '@react-n
|
|
|
2
2
|
import { StackActions, useNavigation } from '@react-navigation/native';
|
|
3
3
|
import React, { useCallback, useEffect, useRef, useState, } from 'react';
|
|
4
4
|
import { Alert, FlatList, Platform, Pressable, StyleSheet, TextInput, View, } from 'react-native';
|
|
5
|
-
import { Badge, ChildNotice, Heading, Icon, Person, Switch, Text, TextButton, } from '../components';
|
|
5
|
+
import { Badge, Button, ChildNotice, Heading, Icon, Person, Switch, Text, TextButton, } from '../components';
|
|
6
|
+
import { ConversationAvatar } from '../components/display/conversation_avatar';
|
|
6
7
|
import { HeaderTextButton } from '../components/display/platform_modal_header_buttons';
|
|
7
8
|
import { useSuspensePaginator, useTheme } from '../hooks';
|
|
8
9
|
import { useConversation, useConversationDelete, useConversationDisableReplies, useConversationMute, useConversationUpdate, } from '../hooks/use_conversation';
|
|
@@ -34,6 +35,7 @@ export function ConversationDetailsScreen({ route }) {
|
|
|
34
35
|
const { mutate: deleteConversation } = useConversationDelete(route.params);
|
|
35
36
|
const { featureEnabled } = useFeatures();
|
|
36
37
|
const granularNotificationsEnabled = featureEnabled(availableFeatures.granular_notifications_ui);
|
|
38
|
+
const customAvatarsEnabled = featureEnabled(availableFeatures.custom_conversation_avatars);
|
|
37
39
|
const showGenderFilter = featureEnabled(availableFeatures.gender_specific_conversations) && !!conversation.genderOption;
|
|
38
40
|
const genderLabel = conversation.genderOption ? genderDisplayLabel(conversation.genderOption) : '';
|
|
39
41
|
const { muted, setMuted } = useConversationMute({ conversation_id });
|
|
@@ -123,6 +125,20 @@ export function ConversationDetailsScreen({ route }) {
|
|
|
123
125
|
});
|
|
124
126
|
}, [HeaderRight, HeaderTitle, navigation]);
|
|
125
127
|
const listData = [
|
|
128
|
+
{
|
|
129
|
+
type: canUpdate && customAvatarsEnabled ? SectionTypes.view : SectionTypes.hidden,
|
|
130
|
+
data: {
|
|
131
|
+
children: (<AvatarCard conversation={conversation} onPress={() => navigation.navigate('AvatarPicker', { conversation_id })}/>),
|
|
132
|
+
},
|
|
133
|
+
sectionOuterStyle: styles.sectionOuterAvatarCard,
|
|
134
|
+
sectionInnerStyle: styles.sectionInnerAvatarCard,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
type: SectionTypes.header,
|
|
138
|
+
data: { title: 'Basic info' },
|
|
139
|
+
showBottomBorder: true,
|
|
140
|
+
sectionInnerStyle: styles.sectionInnerHeaderWithBottomBorder,
|
|
141
|
+
},
|
|
126
142
|
{
|
|
127
143
|
type: SectionTypes.view,
|
|
128
144
|
data: {
|
|
@@ -315,6 +331,13 @@ function NavigableSettingRow({ title, subtitle, onPress }) {
|
|
|
315
331
|
</View>
|
|
316
332
|
</PlatformPressable>);
|
|
317
333
|
}
|
|
334
|
+
function AvatarCard({ conversation, onPress, }) {
|
|
335
|
+
const styles = useStyles();
|
|
336
|
+
return (<View style={styles.avatarCard}>
|
|
337
|
+
<ConversationAvatar conversation={conversation} size="2xl"/>
|
|
338
|
+
<Button title="Update avatar" iconNameLeft="general.pencil" onPress={onPress} variant="outline" appearance="interaction" size="sm"/>
|
|
339
|
+
</View>);
|
|
340
|
+
}
|
|
318
341
|
function TeamsGroup({ teams }) {
|
|
319
342
|
const styles = useStyles();
|
|
320
343
|
if (teams.length === 0)
|
|
@@ -437,6 +460,19 @@ const useStyles = ({ isStart, isEnd } = {}) => {
|
|
|
437
460
|
navigableSettingChevron: {
|
|
438
461
|
color: colors.iconColorDefaultDisabled,
|
|
439
462
|
},
|
|
463
|
+
avatarCard: {
|
|
464
|
+
alignItems: 'center',
|
|
465
|
+
gap: 16,
|
|
466
|
+
},
|
|
467
|
+
sectionOuterAvatarCard: {
|
|
468
|
+
paddingLeft: 0,
|
|
469
|
+
},
|
|
470
|
+
sectionInnerAvatarCard: {
|
|
471
|
+
paddingTop: 24,
|
|
472
|
+
paddingBottom: 24,
|
|
473
|
+
paddingHorizontal: 16,
|
|
474
|
+
alignItems: 'center',
|
|
475
|
+
},
|
|
440
476
|
teamGroup: {
|
|
441
477
|
flexDirection: 'row',
|
|
442
478
|
gap: 4,
|