[Glitch] Change zoom icon in web UI
Port e7fd0985c9 to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
			
			
This commit is contained in:
		
							parent
							
								
									03829d8e1d
								
							
						
					
					
						commit
						a969c6a6a6
					
				| 
						 | 
					@ -153,7 +153,7 @@ class ModalRoot extends PureComponent {
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <div className='modal-root' ref={this.setRef}>
 | 
					      <div className='modal-root' ref={this.setRef}>
 | 
				
			||||||
        <div style={{ pointerEvents: visible ? 'auto' : 'none' }}>
 | 
					        <div style={{ pointerEvents: visible ? 'auto' : 'none' }}>
 | 
				
			||||||
          <div role='presentation' className='modal-root__overlay' onClick={onClose} style={{ backgroundColor: backgroundColor ? `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, 0.7)` : null }} />
 | 
					          <div role='presentation' className='modal-root__overlay' onClick={onClose} style={{ backgroundColor: backgroundColor ? `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, 0.9)` : null }} />
 | 
				
			||||||
          <div role='dialog' className='modal-root__container'>{children}</div>
 | 
					          <div role='dialog' className='modal-root__container'>{children}</div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ export default class ImageLoader extends PureComponent {
 | 
				
			||||||
    width: PropTypes.number,
 | 
					    width: PropTypes.number,
 | 
				
			||||||
    height: PropTypes.number,
 | 
					    height: PropTypes.number,
 | 
				
			||||||
    onClick: PropTypes.func,
 | 
					    onClick: PropTypes.func,
 | 
				
			||||||
    zoomButtonHidden: PropTypes.bool,
 | 
					    zoomedIn: PropTypes.bool,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static defaultProps = {
 | 
					  static defaultProps = {
 | 
				
			||||||
| 
						 | 
					@ -134,7 +134,7 @@ export default class ImageLoader extends PureComponent {
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
    const { alt, lang, src, width, height, onClick } = this.props;
 | 
					    const { alt, lang, src, width, height, onClick, zoomedIn } = this.props;
 | 
				
			||||||
    const { loading } = this.state;
 | 
					    const { loading } = this.state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const className = classNames('image-loader', {
 | 
					    const className = classNames('image-loader', {
 | 
				
			||||||
| 
						 | 
					@ -149,6 +149,7 @@ export default class ImageLoader extends PureComponent {
 | 
				
			||||||
            <div className='loading-bar__container' style={{ width: this.state.width || width }}>
 | 
					            <div className='loading-bar__container' style={{ width: this.state.width || width }}>
 | 
				
			||||||
              <LoadingBar className='loading-bar' loading={1} />
 | 
					              <LoadingBar className='loading-bar' loading={1} />
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <canvas
 | 
					            <canvas
 | 
				
			||||||
              className='image-loader__preview-canvas'
 | 
					              className='image-loader__preview-canvas'
 | 
				
			||||||
              ref={this.setCanvasRef}
 | 
					              ref={this.setCanvasRef}
 | 
				
			||||||
| 
						 | 
					@ -164,7 +165,7 @@ export default class ImageLoader extends PureComponent {
 | 
				
			||||||
            onClick={onClick}
 | 
					            onClick={onClick}
 | 
				
			||||||
            width={width}
 | 
					            width={width}
 | 
				
			||||||
            height={height}
 | 
					            height={height}
 | 
				
			||||||
            zoomButtonHidden={this.props.zoomButtonHidden}
 | 
					            zoomedIn={zoomedIn}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
        )}
 | 
					        )}
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,8 @@ import ReactSwipeableViews from 'react-swipeable-views';
 | 
				
			||||||
import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react';
 | 
					import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react';
 | 
				
			||||||
import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
 | 
					import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
 | 
				
			||||||
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
 | 
					import CloseIcon from '@/material-icons/400-24px/close.svg?react';
 | 
				
			||||||
 | 
					import FitScreenIcon from '@/material-icons/400-24px/fit_screen.svg?react';
 | 
				
			||||||
 | 
					import ActualSizeIcon from '@/svg-icons/actual_size.svg?react';
 | 
				
			||||||
import { getAverageFromBlurhash } from 'flavours/glitch/blurhash';
 | 
					import { getAverageFromBlurhash } from 'flavours/glitch/blurhash';
 | 
				
			||||||
import { GIFV } from 'flavours/glitch/components/gifv';
 | 
					import { GIFV } from 'flavours/glitch/components/gifv';
 | 
				
			||||||
import { Icon }  from 'flavours/glitch/components/icon';
 | 
					import { Icon }  from 'flavours/glitch/components/icon';
 | 
				
			||||||
| 
						 | 
					@ -26,6 +28,8 @@ const messages = defineMessages({
 | 
				
			||||||
  close: { id: 'lightbox.close', defaultMessage: 'Close' },
 | 
					  close: { id: 'lightbox.close', defaultMessage: 'Close' },
 | 
				
			||||||
  previous: { id: 'lightbox.previous', defaultMessage: 'Previous' },
 | 
					  previous: { id: 'lightbox.previous', defaultMessage: 'Previous' },
 | 
				
			||||||
  next: { id: 'lightbox.next', defaultMessage: 'Next' },
 | 
					  next: { id: 'lightbox.next', defaultMessage: 'Next' },
 | 
				
			||||||
 | 
					  zoomIn: { id: 'lightbox.zoom_in', defaultMessage: 'Zoom to actual size' },
 | 
				
			||||||
 | 
					  zoomOut: { id: 'lightbox.zoom_out', defaultMessage: 'Zoom to fit' },
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaModal extends ImmutablePureComponent {
 | 
					class MediaModal extends ImmutablePureComponent {
 | 
				
			||||||
| 
						 | 
					@ -46,30 +50,39 @@ class MediaModal extends ImmutablePureComponent {
 | 
				
			||||||
  state = {
 | 
					  state = {
 | 
				
			||||||
    index: null,
 | 
					    index: null,
 | 
				
			||||||
    navigationHidden: false,
 | 
					    navigationHidden: false,
 | 
				
			||||||
    zoomButtonHidden: false,
 | 
					    zoomedIn: false,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  handleZoomClick = () => {
 | 
				
			||||||
 | 
					    this.setState(prevState => ({
 | 
				
			||||||
 | 
					      zoomedIn: !prevState.zoomedIn,
 | 
				
			||||||
 | 
					    }));
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleSwipe = (index) => {
 | 
					  handleSwipe = (index) => {
 | 
				
			||||||
    this.setState({ index: index % this.props.media.size });
 | 
					    this.setState({
 | 
				
			||||||
 | 
					      index: index % this.props.media.size,
 | 
				
			||||||
 | 
					      zoomedIn: false,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleTransitionEnd = () => {
 | 
					  handleTransitionEnd = () => {
 | 
				
			||||||
    this.setState({
 | 
					    this.setState({
 | 
				
			||||||
      zoomButtonHidden: false,
 | 
					      zoomedIn: false,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleNextClick = () => {
 | 
					  handleNextClick = () => {
 | 
				
			||||||
    this.setState({
 | 
					    this.setState({
 | 
				
			||||||
      index: (this.getIndex() + 1) % this.props.media.size,
 | 
					      index: (this.getIndex() + 1) % this.props.media.size,
 | 
				
			||||||
      zoomButtonHidden: true,
 | 
					      zoomedIn: false,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handlePrevClick = () => {
 | 
					  handlePrevClick = () => {
 | 
				
			||||||
    this.setState({
 | 
					    this.setState({
 | 
				
			||||||
      index: (this.props.media.size + this.getIndex() - 1) % this.props.media.size,
 | 
					      index: (this.props.media.size + this.getIndex() - 1) % this.props.media.size,
 | 
				
			||||||
      zoomButtonHidden: true,
 | 
					      zoomedIn: false,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,7 +91,7 @@ class MediaModal extends ImmutablePureComponent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.setState({
 | 
					    this.setState({
 | 
				
			||||||
      index: index % this.props.media.size,
 | 
					      index: index % this.props.media.size,
 | 
				
			||||||
      zoomButtonHidden: true,
 | 
					      zoomedIn: false,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -130,15 +143,22 @@ class MediaModal extends ImmutablePureComponent {
 | 
				
			||||||
    return this.state.index !== null ? this.state.index : this.props.index;
 | 
					    return this.state.index !== null ? this.state.index : this.props.index;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  toggleNavigation = () => {
 | 
					  handleToggleNavigation = () => {
 | 
				
			||||||
    this.setState(prevState => ({
 | 
					    this.setState(prevState => ({
 | 
				
			||||||
      navigationHidden: !prevState.navigationHidden,
 | 
					      navigationHidden: !prevState.navigationHidden,
 | 
				
			||||||
    }));
 | 
					    }));
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  setRef = c => {
 | 
				
			||||||
 | 
					    this.setState({
 | 
				
			||||||
 | 
					      viewportWidth: c?.clientWidth,
 | 
				
			||||||
 | 
					      viewportHeight: c?.clientHeight,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
    const { media, statusId, lang, intl, onClose } = this.props;
 | 
					    const { media, statusId, lang, intl, onClose } = this.props;
 | 
				
			||||||
    const { navigationHidden } = this.state;
 | 
					    const { navigationHidden, zoomedIn, viewportWidth, viewportHeight } = this.state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const index = this.getIndex();
 | 
					    const index = this.getIndex();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -160,8 +180,8 @@ class MediaModal extends ImmutablePureComponent {
 | 
				
			||||||
            alt={description}
 | 
					            alt={description}
 | 
				
			||||||
            lang={lang}
 | 
					            lang={lang}
 | 
				
			||||||
            key={image.get('url')}
 | 
					            key={image.get('url')}
 | 
				
			||||||
            onClick={this.toggleNavigation}
 | 
					            onClick={this.handleToggleNavigation}
 | 
				
			||||||
            zoomButtonHidden={this.state.zoomButtonHidden}
 | 
					            zoomedIn={zoomedIn}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      } else if (image.get('type') === 'video') {
 | 
					      } else if (image.get('type') === 'video') {
 | 
				
			||||||
| 
						 | 
					@ -229,9 +249,12 @@ class MediaModal extends ImmutablePureComponent {
 | 
				
			||||||
      ));
 | 
					      ));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const currentMedia = media.get(index);
 | 
				
			||||||
 | 
					    const zoomable = currentMedia.get('type') === 'image' && (currentMedia.getIn(['meta', 'original', 'width']) > viewportWidth || currentMedia.getIn(['meta', 'original', 'height']) > viewportHeight);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <div className='modal-root__modal media-modal'>
 | 
					      <div className='modal-root__modal media-modal' ref={this.setRef}>
 | 
				
			||||||
        <div className='media-modal__closer' role='presentation' onClick={onClose} >
 | 
					        <div className='media-modal__closer' role='presentation' onClick={onClose}>
 | 
				
			||||||
          <ReactSwipeableViews
 | 
					          <ReactSwipeableViews
 | 
				
			||||||
            style={swipeableViewsStyle}
 | 
					            style={swipeableViewsStyle}
 | 
				
			||||||
            containerStyle={containerStyle}
 | 
					            containerStyle={containerStyle}
 | 
				
			||||||
| 
						 | 
					@ -245,7 +268,10 @@ class MediaModal extends ImmutablePureComponent {
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div className={navigationClassName}>
 | 
					        <div className={navigationClassName}>
 | 
				
			||||||
          <IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' iconComponent={CloseIcon} onClick={onClose} size={40} />
 | 
					          <div className='media-modal__buttons'>
 | 
				
			||||||
 | 
					            {zoomable && <IconButton title={intl.formatMessage(zoomedIn ? messages.zoomOut : messages.zoomIn)} iconComponent={zoomedIn ? FitScreenIcon : ActualSizeIcon} onClick={this.handleZoomClick} />}
 | 
				
			||||||
 | 
					            <IconButton title={intl.formatMessage(messages.close)} icon='times' iconComponent={CloseIcon} onClick={onClose} />
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          {leftNav}
 | 
					          {leftNav}
 | 
				
			||||||
          {rightNav}
 | 
					          {rightNav}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,6 @@
 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
import { PureComponent } from 'react';
 | 
					import { PureComponent } from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { defineMessages, injectIntl } from 'react-intl';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import FullscreenExitIcon from '@/material-icons/400-24px/fullscreen_exit.svg?react';
 | 
					 | 
				
			||||||
import RectangleIcon from '@/material-icons/400-24px/rectangle.svg?react';
 | 
					 | 
				
			||||||
import { IconButton } from 'flavours/glitch/components/icon_button';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const messages = defineMessages({
 | 
					 | 
				
			||||||
  compress: { id: 'lightbox.compress', defaultMessage: 'Compress image view box' },
 | 
					 | 
				
			||||||
  expand: { id: 'lightbox.expand', defaultMessage: 'Expand image view box' },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const MIN_SCALE = 1;
 | 
					const MIN_SCALE = 1;
 | 
				
			||||||
const MAX_SCALE = 4;
 | 
					const MAX_SCALE = 4;
 | 
				
			||||||
const NAV_BAR_HEIGHT = 66;
 | 
					const NAV_BAR_HEIGHT = 66;
 | 
				
			||||||
| 
						 | 
					@ -104,8 +93,7 @@ class ZoomableImage extends PureComponent {
 | 
				
			||||||
    width: PropTypes.number,
 | 
					    width: PropTypes.number,
 | 
				
			||||||
    height: PropTypes.number,
 | 
					    height: PropTypes.number,
 | 
				
			||||||
    onClick: PropTypes.func,
 | 
					    onClick: PropTypes.func,
 | 
				
			||||||
    zoomButtonHidden: PropTypes.bool,
 | 
					    zoomedIn: PropTypes.bool,
 | 
				
			||||||
    intl: PropTypes.object.isRequired,
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static defaultProps = {
 | 
					  static defaultProps = {
 | 
				
			||||||
| 
						 | 
					@ -131,8 +119,6 @@ class ZoomableImage extends PureComponent {
 | 
				
			||||||
      translateX: null,
 | 
					      translateX: null,
 | 
				
			||||||
      translateY: null,
 | 
					      translateY: null,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    zoomState: 'expand', // 'expand' 'compress'
 | 
					 | 
				
			||||||
    navigationHidden: false,
 | 
					 | 
				
			||||||
    dragPosition: { top: 0, left: 0, x: 0, y: 0 },
 | 
					    dragPosition: { top: 0, left: 0, x: 0, y: 0 },
 | 
				
			||||||
    dragged: false,
 | 
					    dragged: false,
 | 
				
			||||||
    lockScroll: { x: 0, y: 0 },
 | 
					    lockScroll: { x: 0, y: 0 },
 | 
				
			||||||
| 
						 | 
					@ -169,35 +155,20 @@ class ZoomableImage extends PureComponent {
 | 
				
			||||||
    this.container.addEventListener('DOMMouseScroll', handler);
 | 
					    this.container.addEventListener('DOMMouseScroll', handler);
 | 
				
			||||||
    this.removers.push(() => this.container.removeEventListener('DOMMouseScroll', handler));
 | 
					    this.removers.push(() => this.container.removeEventListener('DOMMouseScroll', handler));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.initZoomMatrix();
 | 
					    this._initZoomMatrix();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentWillUnmount () {
 | 
					  componentWillUnmount () {
 | 
				
			||||||
    this.removeEventListeners();
 | 
					    this._removeEventListeners();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentDidUpdate () {
 | 
					  componentDidUpdate (prevProps) {
 | 
				
			||||||
    this.setState({ zoomState: this.state.scale >= this.state.zoomMatrix.rate ? 'compress' : 'expand' });
 | 
					    if (prevProps.zoomedIn !== this.props.zoomedIn) {
 | 
				
			||||||
 | 
					      this._toggleZoom();
 | 
				
			||||||
    if (this.state.scale === MIN_SCALE) {
 | 
					 | 
				
			||||||
      this.container.style.removeProperty('cursor');
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  UNSAFE_componentWillReceiveProps () {
 | 
					  _removeEventListeners () {
 | 
				
			||||||
    // reset when slide to next image
 | 
					 | 
				
			||||||
    if (this.props.zoomButtonHidden) {
 | 
					 | 
				
			||||||
      this.setState({
 | 
					 | 
				
			||||||
        scale: MIN_SCALE,
 | 
					 | 
				
			||||||
        lockTranslate: { x: 0, y: 0 },
 | 
					 | 
				
			||||||
      }, () => {
 | 
					 | 
				
			||||||
        this.container.scrollLeft = 0;
 | 
					 | 
				
			||||||
        this.container.scrollTop = 0;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  removeEventListeners () {
 | 
					 | 
				
			||||||
    this.removers.forEach(listeners => listeners());
 | 
					    this.removers.forEach(listeners => listeners());
 | 
				
			||||||
    this.removers = [];
 | 
					    this.removers = [];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -220,9 +191,6 @@ class ZoomableImage extends PureComponent {
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mouseDownHandler = e => {
 | 
					  mouseDownHandler = e => {
 | 
				
			||||||
    this.container.style.cursor = 'grabbing';
 | 
					 | 
				
			||||||
    this.container.style.userSelect = 'none';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.setState({ dragPosition: {
 | 
					    this.setState({ dragPosition: {
 | 
				
			||||||
      left: this.container.scrollLeft,
 | 
					      left: this.container.scrollLeft,
 | 
				
			||||||
      top: this.container.scrollTop,
 | 
					      top: this.container.scrollTop,
 | 
				
			||||||
| 
						 | 
					@ -246,9 +214,6 @@ class ZoomableImage extends PureComponent {
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mouseUpHandler = () => {
 | 
					  mouseUpHandler = () => {
 | 
				
			||||||
    this.container.style.cursor = 'grab';
 | 
					 | 
				
			||||||
    this.container.style.removeProperty('user-select');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.image.removeEventListener('mousemove', this.mouseMoveHandler);
 | 
					    this.image.removeEventListener('mousemove', this.mouseMoveHandler);
 | 
				
			||||||
    this.image.removeEventListener('mouseup', this.mouseUpHandler);
 | 
					    this.image.removeEventListener('mouseup', this.mouseUpHandler);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
| 
						 | 
					@ -276,13 +241,13 @@ class ZoomableImage extends PureComponent {
 | 
				
			||||||
    const _MAX_SCALE = Math.max(MAX_SCALE, this.state.zoomMatrix.rate);
 | 
					    const _MAX_SCALE = Math.max(MAX_SCALE, this.state.zoomMatrix.rate);
 | 
				
			||||||
    const scale = clamp(MIN_SCALE, _MAX_SCALE, this.state.scale * distance / this.lastDistance);
 | 
					    const scale = clamp(MIN_SCALE, _MAX_SCALE, this.state.scale * distance / this.lastDistance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.zoom(scale, midpoint);
 | 
					    this._zoom(scale, midpoint);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.lastMidpoint = midpoint;
 | 
					    this.lastMidpoint = midpoint;
 | 
				
			||||||
    this.lastDistance = distance;
 | 
					    this.lastDistance = distance;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  zoom(nextScale, midpoint) {
 | 
					  _zoom(nextScale, midpoint) {
 | 
				
			||||||
    const { scale, zoomMatrix } = this.state;
 | 
					    const { scale, zoomMatrix } = this.state;
 | 
				
			||||||
    const { scrollLeft, scrollTop } = this.container;
 | 
					    const { scrollLeft, scrollTop } = this.container;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -318,14 +283,13 @@ class ZoomableImage extends PureComponent {
 | 
				
			||||||
    if (dragged) return;
 | 
					    if (dragged) return;
 | 
				
			||||||
    const handler = this.props.onClick;
 | 
					    const handler = this.props.onClick;
 | 
				
			||||||
    if (handler) handler();
 | 
					    if (handler) handler();
 | 
				
			||||||
    this.setState({ navigationHidden: !this.state.navigationHidden });
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleMouseDown = e => {
 | 
					  handleMouseDown = e => {
 | 
				
			||||||
    e.preventDefault();
 | 
					    e.preventDefault();
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  initZoomMatrix = () => {
 | 
					  _initZoomMatrix = () => {
 | 
				
			||||||
    const { width, height } = this.props;
 | 
					    const { width, height } = this.props;
 | 
				
			||||||
    const { clientWidth, clientHeight } = this.container;
 | 
					    const { clientWidth, clientHeight } = this.container;
 | 
				
			||||||
    const { offsetWidth, offsetHeight } = this.image;
 | 
					    const { offsetWidth, offsetHeight } = this.image;
 | 
				
			||||||
| 
						 | 
					@ -357,10 +321,7 @@ class ZoomableImage extends PureComponent {
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleZoomClick = e => {
 | 
					  _toggleZoom () {
 | 
				
			||||||
    e.preventDefault();
 | 
					 | 
				
			||||||
    e.stopPropagation();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { scale, zoomMatrix } = this.state;
 | 
					    const { scale, zoomMatrix } = this.state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( scale >= zoomMatrix.rate ) {
 | 
					    if ( scale >= zoomMatrix.rate ) {
 | 
				
			||||||
| 
						 | 
					@ -394,10 +355,7 @@ class ZoomableImage extends PureComponent {
 | 
				
			||||||
        this.container.scrollTop = zoomMatrix.scrollTop;
 | 
					        this.container.scrollTop = zoomMatrix.scrollTop;
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
    this.container.style.cursor = 'grab';
 | 
					 | 
				
			||||||
    this.container.style.removeProperty('user-select');
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  setContainerRef = c => {
 | 
					  setContainerRef = c => {
 | 
				
			||||||
    this.container = c;
 | 
					    this.container = c;
 | 
				
			||||||
| 
						 | 
					@ -408,29 +366,16 @@ class ZoomableImage extends PureComponent {
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
    const { alt, lang, src, width, height, intl } = this.props;
 | 
					    const { alt, lang, src, width, height } = this.props;
 | 
				
			||||||
    const { scale, lockTranslate } = this.state;
 | 
					    const { scale, lockTranslate, dragged } = this.state;
 | 
				
			||||||
    const overflow = scale === MIN_SCALE ? 'hidden' : 'scroll';
 | 
					    const overflow = scale === MIN_SCALE ? 'hidden' : 'scroll';
 | 
				
			||||||
    const zoomButtonShouldHide = this.state.navigationHidden || this.props.zoomButtonHidden || this.state.zoomMatrix.rate <= MIN_SCALE ? 'media-modal__zoom-button--hidden' : '';
 | 
					    const cursor = scale === MIN_SCALE ? null : (dragged ? 'grabbing' : 'grab');
 | 
				
			||||||
    const zoomButtonTitle = this.state.zoomState === 'compress' ? intl.formatMessage(messages.compress) : intl.formatMessage(messages.expand);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <>
 | 
					 | 
				
			||||||
        <IconButton
 | 
					 | 
				
			||||||
          className={`media-modal__zoom-button ${zoomButtonShouldHide}`}
 | 
					 | 
				
			||||||
          title={zoomButtonTitle}
 | 
					 | 
				
			||||||
          icon={this.state.zoomState}
 | 
					 | 
				
			||||||
          iconComponent={this.state.zoomState === 'compress' ? FullscreenExitIcon : RectangleIcon}
 | 
					 | 
				
			||||||
          onClick={this.handleZoomClick}
 | 
					 | 
				
			||||||
          size={40}
 | 
					 | 
				
			||||||
          style={{
 | 
					 | 
				
			||||||
            fontSize: '30px', /* Fontawesome's fa-compress fa-expand is larger than fa-close */
 | 
					 | 
				
			||||||
          }}
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      <div
 | 
					      <div
 | 
				
			||||||
        className='zoomable-image'
 | 
					        className='zoomable-image'
 | 
				
			||||||
        ref={this.setContainerRef}
 | 
					        ref={this.setContainerRef}
 | 
				
			||||||
          style={{ overflow }}
 | 
					        style={{ overflow, cursor, userSelect: 'none' }}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <img
 | 
					        <img
 | 
				
			||||||
          role='presentation'
 | 
					          role='presentation'
 | 
				
			||||||
| 
						 | 
					@ -450,10 +395,8 @@ class ZoomableImage extends PureComponent {
 | 
				
			||||||
          onMouseDown={this.handleMouseDown}
 | 
					          onMouseDown={this.handleMouseDown}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      </>
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default injectIntl(ZoomableImage);
 | 
					export default ZoomableImage;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6212,9 +6212,23 @@ a.status-card {
 | 
				
			||||||
  height: 100%;
 | 
					  height: 100%;
 | 
				
			||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &__close,
 | 
					  &__buttons {
 | 
				
			||||||
  &__zoom-button {
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    inset-inline-end: 8px;
 | 
				
			||||||
 | 
					    top: 8px;
 | 
				
			||||||
 | 
					    z-index: 100;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    gap: 8px;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .icon-button {
 | 
				
			||||||
      color: rgba($white, 0.7);
 | 
					      color: rgba($white, 0.7);
 | 
				
			||||||
 | 
					      padding: 8px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      .icon {
 | 
				
			||||||
 | 
					        width: 24px;
 | 
				
			||||||
 | 
					        height: 24px;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      &:hover,
 | 
					      &:hover,
 | 
				
			||||||
      &:focus,
 | 
					      &:focus,
 | 
				
			||||||
| 
						 | 
					@ -6227,6 +6241,7 @@ a.status-card {
 | 
				
			||||||
        background-color: rgba($white, 0.3);
 | 
					        background-color: rgba($white, 0.3);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.media-modal__closer {
 | 
					.media-modal__closer {
 | 
				
			||||||
| 
						 | 
					@ -6385,28 +6400,6 @@ a.status-card {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.media-modal__close {
 | 
					 | 
				
			||||||
  position: absolute;
 | 
					 | 
				
			||||||
  inset-inline-end: 8px;
 | 
					 | 
				
			||||||
  top: 8px;
 | 
					 | 
				
			||||||
  z-index: 100;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.media-modal__zoom-button {
 | 
					 | 
				
			||||||
  position: absolute;
 | 
					 | 
				
			||||||
  inset-inline-end: 64px;
 | 
					 | 
				
			||||||
  top: 8px;
 | 
					 | 
				
			||||||
  z-index: 100;
 | 
					 | 
				
			||||||
  pointer-events: auto;
 | 
					 | 
				
			||||||
  transition: opacity 0.3s linear;
 | 
					 | 
				
			||||||
  will-change: opacity;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.media-modal__zoom-button--hidden {
 | 
					 | 
				
			||||||
  pointer-events: none;
 | 
					 | 
				
			||||||
  opacity: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.onboarding-modal,
 | 
					.onboarding-modal,
 | 
				
			||||||
.error-modal,
 | 
					.error-modal,
 | 
				
			||||||
.embed-modal {
 | 
					.embed-modal {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue