mattermost-mobile/app/screens/edit_profile/components/profile_image_picker.tsx
Elias Nahum 7aa5bd0611
Update Dependencies and bug fixes (#7000)
* update dependencies

* update dependencies

* feedback review

* update @mattermost/react-native-turbo-mailer
2023-01-24 09:14:23 +02:00

152 lines
5.1 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback, useMemo} from 'react';
import {useIntl} from 'react-intl';
import {TouchableOpacity} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import CompassIcon from '@components/compass_icon';
import FormattedText from '@components/formatted_text';
import {ITEM_HEIGHT} from '@components/slide_up_panel_item';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {useIsTablet} from '@hooks/device';
import NetworkManager from '@managers/network_manager';
import {TITLE_HEIGHT} from '@screens/bottom_sheet/content';
import PanelItem from '@screens/edit_profile/components/panel_item';
import {bottomSheet} from '@screens/navigation';
import PickerUtil from '@utils/file/file_picker';
import {bottomSheetSnapPoint} from '@utils/helpers';
import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
import type {Client} from '@client/rest';
import type UserModel from '@typings/database/models/servers/user';
const hitSlop = {top: 100, bottom: 20, right: 20, left: 100};
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
return {
touchable: {
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderColor: theme.centerChannelBg,
borderRadius: 18,
height: 36,
width: 36,
position: 'absolute',
bottom: 0,
right: 0,
backgroundColor: theme.centerChannelBg,
},
title: {
...typography('Heading', 600, 'SemiBold'),
color: theme.centerChannelColor,
marginBottom: 8,
},
};
});
type ImagePickerProps = {
onRemoveProfileImage: UploadExtractedFile;
uploadFiles: UploadExtractedFile;
user: UserModel;
};
const hasPictureUrl = (user: UserModel, serverUrl: string) => {
const {id, lastPictureUpdate} = user;
let client: Client | undefined;
let profileImageUrl: string | undefined;
try {
client = NetworkManager.getClient(serverUrl);
profileImageUrl = client.getProfilePictureUrl(id, lastPictureUpdate);
} catch {
return false;
}
// Check if image url includes query string for timestamp. If so,
// it means the image has been updated from the default, i.e. '.../image?_=1544159746868'
return Boolean(profileImageUrl?.includes('image?_'));
};
const ProfileImagePicker = ({
onRemoveProfileImage,
uploadFiles,
user,
}: ImagePickerProps) => {
const theme = useTheme();
const intl = useIntl();
const {bottom} = useSafeAreaInsets();
const serverUrl = useServerUrl();
const pictureUtils = useMemo(() => new PickerUtil(intl, uploadFiles), [uploadFiles, intl]);
const canRemovePicture = hasPictureUrl(user, serverUrl);
const styles = getStyleSheet(theme);
const isTablet = useIsTablet();
const showFileAttachmentOptions = useCallback(preventDoubleTap(() => {
const renderContent = () => {
return (
<>
{!isTablet &&
<FormattedText
id='user.edit_profile.profile_photo.change_photo'
defaultMessage='Change profile photo'
style={styles.title}
/>
}
<PanelItem
pickerAction='takePhoto'
pictureUtils={pictureUtils}
/>
<PanelItem
pickerAction='browsePhotoLibrary'
pictureUtils={pictureUtils}
/>
<PanelItem
pickerAction='browseFiles'
pictureUtils={pictureUtils}
/>
{canRemovePicture && (
<PanelItem
pickerAction='removeProfilePicture'
onRemoveProfileImage={onRemoveProfileImage}
/>
)}
</>
);
};
const snapPoint = bottomSheetSnapPoint(4, ITEM_HEIGHT, bottom) + TITLE_HEIGHT;
return bottomSheet({
closeButtonId: 'close-edit-profile',
renderContent,
snapPoints: [1, snapPoint],
title: 'Change profile photo',
theme,
});
}), [canRemovePicture, onRemoveProfileImage, bottom, pictureUtils, theme]);
return (
<TouchableOpacity
onPress={showFileAttachmentOptions}
hitSlop={hitSlop}
style={styles.touchable}
>
<CompassIcon
name='camera-outline'
size={24}
color={changeOpacity(theme.centerChannelColor, 0.6)}
/>
</TouchableOpacity>
);
};
export default ProfileImagePicker;