From 0edcc139f4155ab436ddc5ef27f815a9cd984797 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Mon, 24 Sep 2018 04:23:40 -0300 Subject: [PATCH] Make the image preview smoother (#2147) * Make the image preview smoother --- .../__snapshots__/image_preview.test.js.snap | 257 ++++++++++++++++++ app/screens/image_preview/image_preview.js | 94 +------ .../image_preview/image_preview.test.js | 87 ++++++ package.json | 5 +- 4 files changed, 360 insertions(+), 83 deletions(-) create mode 100644 app/screens/image_preview/__snapshots__/image_preview.test.js.snap create mode 100644 app/screens/image_preview/image_preview.test.js diff --git a/app/screens/image_preview/__snapshots__/image_preview.test.js.snap b/app/screens/image_preview/__snapshots__/image_preview.test.js.snap new file mode 100644 index 000000000..80973f4e5 --- /dev/null +++ b/app/screens/image_preview/__snapshots__/image_preview.test.js.snap @@ -0,0 +1,257 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ImagePreview should match snapshot 1`] = ` + + + + + + + + + + + 1/2 + + + + + + + + + + + Caption 1 + + + + + + +`; + +exports[`ImagePreview should match snapshot, renderDownloadButton 1`] = ` + + + +`; diff --git a/app/screens/image_preview/image_preview.js b/app/screens/image_preview/image_preview.js index 681a8a40a..082ce50fa 100644 --- a/app/screens/image_preview/image_preview.js +++ b/app/screens/image_preview/image_preview.js @@ -9,7 +9,6 @@ import { Image, Platform, SafeAreaView, - ScrollView, StatusBar, StyleSheet, Text, @@ -27,7 +26,6 @@ import EventEmitter from 'mattermost-redux/utils/event_emitter'; import FileAttachmentDocument from 'app/components/file_attachment_list/file_attachment_document'; import FileAttachmentIcon from 'app/components/file_attachment_list/file_attachment_icon'; -import ProgressiveImage from 'app/components/progressive_image'; import {DeviceTypes, NavigationTypes, PermissionTypes} from 'app/constants'; import {getLocalFilePathFromFile, isDocument, isVideo} from 'app/utils/file'; import {emptyFunction} from 'app/utils/general'; @@ -104,7 +102,7 @@ export default class ImagePreview extends PureComponent { const {getItemMeasures, navigator} = this.props; const {index} = this.state; - this.setState({animating: true, gallery: false, hide: false}); + this.setState({animating: true}); navigator.setStyle({ screenBackgroundColor: 'transparent', }); @@ -124,10 +122,6 @@ export default class ImagePreview extends PureComponent { this.setState({index}); }; - handleGalleryLayout = () => { - this.setState({hide: true}); - }; - handleSwipedVertical = (evt, gestureState) => { if (Math.abs(gestureState.dy) > 150) { this.close(); @@ -178,44 +172,6 @@ export default class ImagePreview extends PureComponent { }; }; - getSwipeableStyle = () => { - const {deviceHeight, deviceWidth, files} = this.props; - const {origin, target, index} = this.state; - const inputRange = [0, 1]; - - let toHeight = deviceHeight; - let toWidth = deviceWidth; - if (files[index].dimensions) { - const {height, width} = files[index].dimensions; - if (width < deviceWidth) { - toWidth = width; - } - - if (height < deviceWidth) { - toHeight = height; - } - } - - return { - left: this.openAnim.interpolate({ - inputRange, - outputRange: [origin.x, target.x], - }), - top: this.openAnim.interpolate({ - inputRange, - outputRange: [origin.y, target.y], - }), - width: this.openAnim.interpolate({ - inputRange, - outputRange: [origin.width, toWidth], - }), - height: this.openAnim.interpolate({ - inputRange, - outputRange: [origin.height, toHeight], - }), - }; - }; - renderAttachmentDocument = (file) => { const {canDownloadFiles, theme, navigator} = this.props; @@ -294,7 +250,7 @@ export default class ImagePreview extends PureComponent { return null; }; - renderDownloader() { + renderDownloader = () => { const {deviceHeight, deviceWidth} = this.props; const file = this.getCurrentFile(); @@ -310,9 +266,9 @@ export default class ImagePreview extends PureComponent { onDownloadSuccess={this.hideDownloader} /> ); - } + }; - renderFooter() { + renderFooter = () => { const {files} = this.props; const {index} = this.state; const footer = this.getHeaderFooterStyle(); @@ -331,16 +287,15 @@ export default class ImagePreview extends PureComponent { ); - } + }; - renderGallery() { + renderGallery = () => { return ( ); - } + }; - renderHeader() { + renderHeader = () => { const {files} = this.props; const {index} = this.state; const header = this.getHeaderFooterStyle(); @@ -377,7 +332,7 @@ export default class ImagePreview extends PureComponent { ); - } + }; renderImageComponent = (imageProps, imageDimensions) => { if (imageDimensions) { @@ -398,7 +353,7 @@ export default class ImagePreview extends PureComponent { } return null; - } + }; renderOtherItems = (index) => { const {files} = this.props; @@ -417,28 +372,6 @@ export default class ImagePreview extends PureComponent { return ; }; - renderSelectedItem = () => { - const {hide} = this.state; - const file = this.getCurrentFile(); - - if (hide || !file || !file.source || !file.source.uri || isDocument(file.data) || isVideo(file.data)) { - return null; - } - - const containerStyle = this.getSwipeableStyle(); - return ( - - - - - - ); - }; - renderVideoPreview = (file) => { const {deviceHeight, deviceWidth, theme} = this.props; @@ -611,9 +544,7 @@ export default class ImagePreview extends PureComponent { }; startOpenAnimation = () => { - this.animateOpenAnimToValue(1, () => { - this.setState({gallery: true}); - }); + this.animateOpenAnimToValue(1); }; render() { @@ -622,8 +553,7 @@ export default class ImagePreview extends PureComponent { return ( - {this.renderSelectedItem()} - {this.state.gallery && this.renderGallery()} + {this.renderGallery()} {this.renderHeader()} {this.renderFooter()} diff --git a/app/screens/image_preview/image_preview.test.js b/app/screens/image_preview/image_preview.test.js new file mode 100644 index 000000000..e4e31a0f6 --- /dev/null +++ b/app/screens/image_preview/image_preview.test.js @@ -0,0 +1,87 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; +import {shallow} from 'enzyme'; +import { + TouchableOpacity, +} from 'react-native'; + +import Preferences from 'mattermost-redux/constants/preferences'; + +import ImagePreview from './image_preview'; + +jest.useFakeTimers(); +jest.mock('react-intl'); +jest.mock('react-native-doc-viewer', () => { + return { + OpenFile: jest.fn(), + }; +}); + +describe('ImagePreview', () => { + const baseProps = { + canDownloadFiles: true, + deviceHeight: 400, + deviceWidth: 300, + files: [ + {caption: 'Caption 1', source: 'source', data: 'data'}, + {caption: 'Caption 2', source: 'source', data: 'data'}, + ], + getItemMeasures: jest.fn(), + index: 0, + navigator: {setStyle: jest.fn()}, + origin: {}, + target: {}, + theme: Preferences.THEMES.default, + }; + + test('should match snapshot', () => { + const wrapper = shallow( + , + {context: {intl: {formatMessage: jest.fn()}}}, + ); + + expect(wrapper.getElement()).toMatchSnapshot(); + expect(wrapper.find(TouchableOpacity).first().exists()).toEqual(true); + }); + + test('should match snapshot, renderDownloadButton', () => { + const wrapper = shallow( + , + {context: {intl: {formatMessage: jest.fn()}}}, + ); + + expect(wrapper.instance().renderDownloadButton()).toMatchSnapshot(); + }); + + test('should match state on handleChangeImage', () => { + const wrapper = shallow( + , + {context: {intl: {formatMessage: jest.fn()}}}, + ); + + wrapper.setState({index: 0}); + wrapper.instance().handleChangeImage(1); + + expect(wrapper.state('index')).toEqual(1); + }); + + test('should match call getItemMeasures & navigator.setStyle on close', () => { + const getItemMeasures = jest.fn(); + const navigator = {setStyle: jest.fn()}; + const wrapper = shallow( + , + {context: {intl: {formatMessage: jest.fn()}}}, + ); + + wrapper.instance().close(); + + expect(navigator.setStyle).toHaveBeenCalledTimes(2); + expect(navigator.setStyle).toBeCalledWith({screenBackgroundColor: 'transparent'}); + }); +}); diff --git a/package.json b/package.json index 02593f3bb..b980092c7 100644 --- a/package.json +++ b/package.json @@ -127,6 +127,9 @@ "setupTestFrameworkScriptFile": "/test/setup.js", "testPathIgnorePatterns": [ "/node_modules/" - ] + ], + "moduleNameMapper": { + "assets/images/video_player/(.*).png": "/dist/assets/images/video_player/$1@2x.png" + } } }