[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,52 +366,37 @@ 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 ( | ||||||
|       <> |       <div | ||||||
|         <IconButton |         className='zoomable-image' | ||||||
|           className={`media-modal__zoom-button ${zoomButtonShouldHide}`} |         ref={this.setContainerRef} | ||||||
|           title={zoomButtonTitle} |         style={{ overflow, cursor, userSelect: 'none' }} | ||||||
|           icon={this.state.zoomState} |       > | ||||||
|           iconComponent={this.state.zoomState === 'compress' ? FullscreenExitIcon : RectangleIcon} |         <img | ||||||
|           onClick={this.handleZoomClick} |           role='presentation' | ||||||
|           size={40} |           ref={this.setImageRef} | ||||||
|  |           alt={alt} | ||||||
|  |           title={alt} | ||||||
|  |           lang={lang} | ||||||
|  |           src={src} | ||||||
|  |           width={width} | ||||||
|  |           height={height} | ||||||
|           style={{ |           style={{ | ||||||
|             fontSize: '30px', /* Fontawesome's fa-compress fa-expand is larger than fa-close */ |             transform: `scale(${scale}) translate(-${lockTranslate.x}px, -${lockTranslate.y}px)`, | ||||||
|  |             transformOrigin: '0 0', | ||||||
|           }} |           }} | ||||||
|  |           draggable={false} | ||||||
|  |           onClick={this.handleClick} | ||||||
|  |           onMouseDown={this.handleMouseDown} | ||||||
|         /> |         /> | ||||||
|         <div |       </div> | ||||||
|           className='zoomable-image' |  | ||||||
|           ref={this.setContainerRef} |  | ||||||
|           style={{ overflow }} |  | ||||||
|         > |  | ||||||
|           <img |  | ||||||
|             role='presentation' |  | ||||||
|             ref={this.setImageRef} |  | ||||||
|             alt={alt} |  | ||||||
|             title={alt} |  | ||||||
|             lang={lang} |  | ||||||
|             src={src} |  | ||||||
|             width={width} |  | ||||||
|             height={height} |  | ||||||
|             style={{ |  | ||||||
|               transform: `scale(${scale}) translate(-${lockTranslate.x}px, -${lockTranslate.y}px)`, |  | ||||||
|               transformOrigin: '0 0', |  | ||||||
|             }} |  | ||||||
|             draggable={false} |  | ||||||
|             onClick={this.handleClick} |  | ||||||
|             onMouseDown={this.handleMouseDown} |  | ||||||
|           /> |  | ||||||
|         </div> |  | ||||||
|       </> |  | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default injectIntl(ZoomableImage); | export default ZoomableImage; | ||||||
|  |  | ||||||
|  | @ -6212,19 +6212,34 @@ a.status-card { | ||||||
|   height: 100%; |   height: 100%; | ||||||
|   position: relative; |   position: relative; | ||||||
| 
 | 
 | ||||||
|   &__close, |   &__buttons { | ||||||
|   &__zoom-button { |     position: absolute; | ||||||
|     color: rgba($white, 0.7); |     inset-inline-end: 8px; | ||||||
|  |     top: 8px; | ||||||
|  |     z-index: 100; | ||||||
|  |     display: flex; | ||||||
|  |     gap: 8px; | ||||||
|  |     align-items: center; | ||||||
| 
 | 
 | ||||||
|     &:hover, |     .icon-button { | ||||||
|     &:focus, |       color: rgba($white, 0.7); | ||||||
|     &:active { |       padding: 8px; | ||||||
|       color: $white; |  | ||||||
|       background-color: rgba($white, 0.15); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     &:focus { |       .icon { | ||||||
|       background-color: rgba($white, 0.3); |         width: 24px; | ||||||
|  |         height: 24px; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       &:hover, | ||||||
|  |       &:focus, | ||||||
|  |       &:active { | ||||||
|  |         color: $white; | ||||||
|  |         background-color: rgba($white, 0.15); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       &:focus { | ||||||
|  |         background-color: rgba($white, 0.3); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -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