diff --git a/background.html b/background.html index 98b8b3c044e..a06ad0abc48 100644 --- a/background.html +++ b/background.html @@ -100,6 +100,7 @@ </div> </div> </div> + <div class='lightboxContainer'></div> </script> <script type='text/x-tmpl-mustache' id='scroll-down-button-view'> <button class='text {{ cssClass }}' alt='{{ moreBelow }}'> @@ -223,15 +224,6 @@ <span class='time'>0:00</span> <button class='close'><span class='icon'></span></button> </script> - <script type='text/x-tmpl-mustache' id='lightbox'> - <div class='content'> - <div class='controls'> - <a class='x close' alt='Close image.' href='#'></a> - <a class='save' alt='Save as...' href='#'></a> - </div> - <img class='image' src='{{ url }}' /> - </div> - </script> <script type='text/x-tmpl-mustache' id='confirmation-dialog'> <div class="content"> <div class='message'>{{ message }}</div> diff --git a/js/views/attachment_view.js b/js/views/attachment_view.js index b82614ef374..b1544ff2741 100644 --- a/js/views/attachment_view.js +++ b/js/views/attachment_view.js @@ -4,6 +4,7 @@ /* global moment: false */ /* global i18n: false */ +/* global Signal: false */ /* global textsecure: false */ /* global Whisper: false */ @@ -92,8 +93,8 @@ unload() { this.blob = null; - if (this.lightBoxView) { - this.lightBoxView.remove(); + if (this.lightboxView) { + this.lightboxView.remove(); } if (this.fileView) { this.fileView.remove(); @@ -111,14 +112,26 @@ } }, onClick() { - if (this.isImage()) { - this.lightBoxView = new Whisper.LightboxView({ model: this }); - this.lightBoxView.render(); - this.lightBoxView.$el.appendTo(this.el); - this.lightBoxView.$el.trigger('show'); - } else { + if (!this.isImage()) { this.saveFile(); + return; } + + const lightboxContainer = document.querySelector('.lightboxContainer'); + lightboxContainer.innerHTML = ''; + lightboxContainer.style.display = 'block'; + + const props = { + imageURL: this.objectUrl, + }; + this.lightboxView = new Whisper.ReactWrapperView({ + Component: Signal.Components.Lightbox, + props, + onClose: () => { + lightboxContainer.style.display = 'none'; + }, + }); + lightboxContainer.appendChild(this.lightboxView.el); }, isVoiceMessage() { // eslint-disable-next-line no-bitwise diff --git a/js/views/inbox_view.js b/js/views/inbox_view.js index 2263577e1b1..cd759ee2987 100644 --- a/js/views/inbox_view.js +++ b/js/views/inbox_view.js @@ -172,7 +172,6 @@ 'click .conversation': 'focusConversation', 'select .gutter .conversation-list-item': 'openConversation', 'input input.search': 'filterContacts', - 'show .lightbox': 'showLightbox', }, startConnectionListener() { this.interval = setInterval(() => { @@ -259,9 +258,6 @@ this.focusConversation(); } }, - showLightbox(e) { - this.$el.append(e.target); - }, closeRecording(e) { if (e && this.$(e.target).closest('.capture-audio').length > 0) { return; diff --git a/preload.js b/preload.js index 8b6eaa2a3c8..aa19f884f7d 100644 --- a/preload.js +++ b/preload.js @@ -162,6 +162,8 @@ window.Signal.Debug = require('./js/modules/debug'); window.Signal.HTML = require('./ts/html'); window.Signal.Logs = require('./js/modules/logs'); +// React components +const { Lightbox } = require('./ts/components/Lightbox'); const { MediaGallery } = require('./ts/components/conversation/media-gallery/MediaGallery'); const { Quote } = require('./ts/components/conversation/Quote'); @@ -170,6 +172,7 @@ const PropTypesMessage = require('./ts/components/conversation/media-gallery/propTypes/Message'); window.Signal.Components = { + Lightbox, MediaGallery, PropTypes: { Message: PropTypesMessage, diff --git a/stylesheets/_lightbox.scss b/stylesheets/_lightbox.scss index c8328364993..bc34689b7db 100644 --- a/stylesheets/_lightbox.scss +++ b/stylesheets/_lightbox.scss @@ -1,59 +1,9 @@ -.lightbox { - &.modal { - padding: 30px; - text-align: center; - background-color: rgba(0,0,0,0.8); - - .content { - margin: 0; - padding: 0 60px; - max-width: 100%; - height: 100%; - box-shadow: none; - background: transparent; - - img { - display: block; - margin: auto; - max-width: 100%; - max-height: 100%; - } - } - - .controls { - position: absolute; - top: 0; - right: 0; - width: 50px; - } - - a { - background: transparent; - width: 50px; - height: 50px; - margin-bottom: 10px; - - display: inline-block; - cursor: pointer; - border-radius: 50%; - padding: 3px; - - &:before { - content: ''; - display: block; - width: 100%; - height: 100%; - } - - &:hover { - background: $grey; - } - } - - .save { - &:before { - @include color-svg('../images/save.svg', white); - } - } - } +.lightboxContainer { + display: none; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: $z-index-modal; } diff --git a/stylesheets/_variables.scss b/stylesheets/_variables.scss index 0b44fef8c1f..9847f6de8e0 100644 --- a/stylesheets/_variables.scss +++ b/stylesheets/_variables.scss @@ -12,6 +12,8 @@ $grey_d: #454545; $green: #47D647; $red: #EF8989; +$z-index-modal: 100; + @font-face { font-family: 'Roboto-Light'; src: url('../fonts/Roboto-Light.ttf') format('truetype'); diff --git a/ts/components/Lightbox.tsx b/ts/components/Lightbox.tsx new file mode 100644 index 00000000000..ef3760eddfc --- /dev/null +++ b/ts/components/Lightbox.tsx @@ -0,0 +1,40 @@ +/** + * @prettier + */ +import React from 'react'; + + +interface Props { + imageURL?: string; + onClose: () => void; + close: () => void; +} + +const styles = { + container: { + backgroundColor: 'rgba(0, 0, 0, 0.8)', + padding: 20, + width: '100%', + height: '100%', + }, + image: { + maxWidth: '100%', + maxHeight: '100%', + objectFit: 'cover', + } +}; + +export class Lightbox extends React.Component<Props, {}> { + public render() { + const { imageURL } = this.props; + return ( + <div style={styles.container}> + <img + style={styles.image} + src={imageURL} + /> + <button onClick={this.props.close}>Close</button> + </div> + ); + } +}