diff --git a/app/components/post_list/post/body/files/file_icon.tsx b/app/components/post_list/post/body/files/file_icon.tsx index 1d74ee051..2799a7d75 100644 --- a/app/components/post_list/post/body/files/file_icon.tsx +++ b/app/components/post_list/post/body/files/file_icon.tsx @@ -25,21 +25,21 @@ const BLUE_ICON = '#338AFF'; const RED_ICON = '#ED522A'; const GREEN_ICON = '#1CA660'; const GRAY_ICON = '#999999'; -const FAILED_ICON_NAME_AND_COLOR = ['jumbo-attachment-image-broken', GRAY_ICON]; +const FAILED_ICON_NAME_AND_COLOR = ['file-image-broken-outline-large', GRAY_ICON]; const ICON_NAME_AND_COLOR_FROM_FILE_TYPE: Record = { - audio: ['jumbo-attachment-audio', BLUE_ICON], - code: ['jumbo-attachment-code', BLUE_ICON], - image: ['jumbo-attachment-image', BLUE_ICON], + audio: ['file-audio-outline-large', BLUE_ICON], + code: ['file-code-outline-large', BLUE_ICON], + image: ['file-image-outline-large', BLUE_ICON], smallImage: ['image-outline', BLUE_ICON], - other: ['jumbo-attachment-generic', BLUE_ICON], - patch: ['jumbo-attachment-patch', BLUE_ICON], - pdf: ['jumbo-attachment-pdf', RED_ICON], - presentation: ['jumbo-attachment-powerpoint', RED_ICON], - spreadsheet: ['jumbo-attachment-excel', GREEN_ICON], - text: ['jumbo-attachment-text', GRAY_ICON], - video: ['jumbo-attachment-video', BLUE_ICON], - word: ['jumbo-attachment-word', BLUE_ICON], - zip: ['jumbo-attachment-zip', BLUE_ICON], + other: ['file-generic-outline-large', BLUE_ICON], + patch: ['file-patch-outline-large', BLUE_ICON], + pdf: ['file-pdf-outline-large', RED_ICON], + presentation: ['file-powerpoint-outline-large', RED_ICON], + spreadsheet: ['file-excel-outline-large', GREEN_ICON], + text: ['file-text-outline-large', GRAY_ICON], + video: ['file-video-outline-large', BLUE_ICON], + word: ['file-word-outline-large', BLUE_ICON], + zip: ['file-zip-outline-large', BLUE_ICON], }; const styles = StyleSheet.create({ diff --git a/app/components/post_list/post/body/files/files.tsx b/app/components/post_list/post/body/files/files.tsx index 90882a301..ab989324f 100644 --- a/app/components/post_list/post/body/files/files.tsx +++ b/app/components/post_list/post/body/files/files.tsx @@ -1,7 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useEffect, useRef, useState} from 'react'; +import React, {useEffect, useMemo, useState} from 'react'; import {DeviceEventEmitter, StyleProp, StyleSheet, View, ViewStyle} from 'react-native'; import {Client4} from '@client/rest'; @@ -46,10 +46,10 @@ const Files = ({canDownloadFiles, failed, files, isReplyPost, postId, theme}: Fi const [inViewPort, setInViewPort] = useState(false); const permanentSidebar = usePermanentSidebar(); const isSplitView = useSplitView(); - const imageAttachments = useRef([]).current; - const nonImageAttachments = useRef([]).current; + const {imageAttachments, nonImageAttachments} = useMemo(() => { + const images: FileInfo[] = []; + const nonImages: FileInfo[] = []; - if (!imageAttachments.length && !nonImageAttachments.length) { files.reduce((info, file) => { if (isImage(file)) { let uri; @@ -58,15 +58,17 @@ const Files = ({canDownloadFiles, failed, files, isReplyPost, postId, theme}: Fi } else { uri = isGif(file) ? Client4.getFileUrl(file.id, 0) : Client4.getFilePreviewUrl(file.id, 0); } - info.imageAttachments.push({...file, uri}); + info.images.push({...file, uri}); } else { - info.nonImageAttachments.push(file); + info.nonImages.push(file); } return info; - }, {imageAttachments, nonImageAttachments}); - } + }, {images, nonImages}); - const filesForGallery = useRef(imageAttachments.concat(nonImageAttachments)).current; + return {imageAttachments: images, nonImageAttachments: nonImages}; + }, [files]); + + const filesForGallery = imageAttachments.concat(nonImageAttachments); const attachmentIndex = (fileId: string) => { return filesForGallery.findIndex((file) => file.id === fileId) || 0; }; diff --git a/app/screens/gallery/gallery.js b/app/screens/gallery/gallery.js index 24c822fda..70bd47c69 100644 --- a/app/screens/gallery/gallery.js +++ b/app/screens/gallery/gallery.js @@ -16,8 +16,6 @@ import GalleryViewer from './gallery_viewer'; export default class Gallery extends PureComponent { static propTypes = { componentId: PropTypes.string.isRequired, - deviceHeight: PropTypes.number.isRequired, - deviceWidth: PropTypes.number.isRequired, files: PropTypes.array, index: PropTypes.number.isRequired, theme: PropTypes.object.isRequired, @@ -152,19 +150,15 @@ export default class Gallery extends PureComponent { }; render() { - const {deviceHeight, deviceWidth, files, theme} = this.props; + const {files, theme} = this.props; const {index, footerVisible} = this.state; return ( <> deviceHeight} onClose={this.close} onPageSelected={this.handlePageSelected} onTap={this.handleTapped} diff --git a/app/screens/gallery/gallery_viewer.tsx b/app/screens/gallery/gallery_viewer.tsx index 8f2ff8530..b6fa1b23f 100644 --- a/app/screens/gallery/gallery_viewer.tsx +++ b/app/screens/gallery/gallery_viewer.tsx @@ -2,7 +2,7 @@ // See LICENSE.txt for license information. import React, {useEffect, useMemo, useRef, useState} from 'react'; -import {Platform, StyleSheet, View} from 'react-native'; +import {Platform, StyleSheet, useWindowDimensions, View} from 'react-native'; import {PanGestureHandler, PinchGestureHandler, State, TapGestureHandler, TapGestureHandlerStateChangeEvent} from 'react-native-gesture-handler'; import Animated, {abs, add, and, call, clockRunning, cond, divide, eq, greaterOrEq, greaterThan, multiply, neq, not, onChange, set, sub, useCode, EasingNode, ceil} from 'react-native-reanimated'; import {clamp, snapPoint, timing, useClock, usePanGestureHandler, usePinchGestureHandler, useTapGestureHandler, useValue, vec} from 'react-native-redash/lib/module/v1'; @@ -18,34 +18,40 @@ import GalleryVideo from './gallery_video'; import type {GalleryProps} from '@mm-types/screens/gallery'; -const itemTopStyle = (props: GalleryProps): number => { +type GalleryStyle = { + count: number; + height: number; + width: number; +} + +const itemTopStyle = (footerVisible: boolean, isLandscape: boolean): number => { if (Platform.OS === 'android') { - if (props.footerVisible) { - return props.isLandscape ? -64 : -99; + if (footerVisible) { + return isLandscape ? -64 : -99; } - return props.isLandscape ? -6 : -41; + return isLandscape ? -6 : -41; } return 0; }; -const getStyles = makeStyleSheetFromTheme((props: GalleryProps) => ({ +const getStyles = makeStyleSheetFromTheme(({count, width, height}: GalleryStyle) => ({ container: { ...StyleSheet.absoluteFillObject, }, items: { - width: (props.width * props.files.length), - height: props.height, + width: (width * count), + height, flexDirection: 'row', alignItems: 'center', }, item: { alignItems: 'center', - height: props.height, + height, justifyContent: 'center', overflow: 'hidden', - width: props.width, + width, }, center: { justifyContent: 'center', @@ -53,12 +59,13 @@ const getStyles = makeStyleSheetFromTheme((props: GalleryProps) => ({ })); const GalleryViewer = (props: GalleryProps) => { - const {files, height, initialIndex, width} = props; + const {files, initialIndex} = props; const [enabled, setEnabled] = useState(false); const [tapEnabled, setTapEnabled] = useState(true); const [currentIndex, setCurrentIndex] = useState(initialIndex); - const styles = getStyles(props); - const topValue = itemTopStyle(props); + const {height, width} = useWindowDimensions(); + const styles = getStyles({width, height, count: files.length}); + const topValue = itemTopStyle(props.footerVisible, width > height); const top = useRef(useValue(topValue)).current; const canvas = useMemo(() => vec.create(width, height), [width]); diff --git a/app/screens/gallery/index.js b/app/screens/gallery/index.js index f5058e750..8e657dc01 100644 --- a/app/screens/gallery/index.js +++ b/app/screens/gallery/index.js @@ -4,13 +4,11 @@ import {connect} from 'react-redux'; import {getTheme} from '@mm-redux/selectors/entities/preferences'; -import {getDimensions} from '@selectors/device'; import Gallery from './gallery'; function mapStateToProps(state) { return { - ...getDimensions(state), theme: getTheme(state), }; } diff --git a/types/screens/gallery.d.ts b/types/screens/gallery.d.ts index 4b2de333b..582ba3364 100644 --- a/types/screens/gallery.d.ts +++ b/types/screens/gallery.d.ts @@ -61,13 +61,11 @@ export interface FooterRef { export interface GalleryProps { files: Array; footerVisible: boolean; - height: number; initialIndex: number; isLandscape: boolean; onClose: CallbackFunctionWithoutArguments; onPageSelected: (index: number) => void; onTap: CallbackFunctionWithoutArguments; - width: number; theme: Theme; }