From 578e757d090b349fa996df6d3be7607b9216c563 Mon Sep 17 00:00:00 2001 From: Mélanie Chauvel Date: Tue, 27 Oct 2020 02:58:47 +0100 Subject: [Glitch] Make click area of video/audio player buttons bigger in WebUI Port a5afbb62d25306dc9d28fa8d0e85edf02c63d2a3 to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/styles/components/media.scss | 30 ++++++++-------------- 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/styles/components/media.scss b/app/javascript/flavours/glitch/styles/components/media.scss index 58bdb642f..f504fa91e 100644 --- a/app/javascript/flavours/glitch/styles/components/media.scss +++ b/app/javascript/flavours/glitch/styles/components/media.scss @@ -385,7 +385,6 @@ } .video-player__controls { - padding: 0 15px; padding-top: 10px; background: transparent; } @@ -512,7 +511,8 @@ &__buttons-bar { display: flex; justify-content: space-between; - padding-bottom: 10px; + padding-bottom: 8px; + margin: 0 -5px; .video-player__download__icon { color: inherit; @@ -536,22 +536,13 @@ overflow: hidden; text-overflow: ellipsis; - &.left { - button { - padding-left: 0; - } - } - - &.right { - button { - padding-right: 0; - } - } + .player-button { + display: inline-block; + outline: 0; - button { flex: 0 0 auto; background: transparent; - padding: 2px 10px; + padding: 5px; font-size: 16px; border: 0; color: rgba($white, 0.75); @@ -569,6 +560,7 @@ flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; + margin: 0 5px; } &__time-sep, @@ -688,7 +680,7 @@ display: block; position: absolute; height: 4px; - top: 10px; + top: 14px; } &__progress, @@ -697,7 +689,7 @@ position: absolute; height: 4px; border-radius: 4px; - top: 10px; + top: 14px; background: lighten($ui-highlight-color, 8%); } @@ -712,7 +704,7 @@ border-radius: 50%; width: 12px; height: 12px; - top: 6px; + top: 10px; margin-left: -6px; background: lighten($ui-highlight-color, 8%); box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2); @@ -736,7 +728,7 @@ &.detailed, &.fullscreen { .video-player__buttons { - button { + .player-button { padding-top: 10px; padding-bottom: 10px; } -- cgit From 078744f210add1edc988142fad3815d4fb92de01 Mon Sep 17 00:00:00 2001 From: Mélanie Chauvel Date: Tue, 27 Oct 2020 03:00:47 +0100 Subject: [Glitch] Make visibility icon clickable as part of the time of a toot Port 1d07f51039625c2eafa7eb0b1b6d5a7f8cf00e41 to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/features/ui/components/boost_modal.js | 5 +++-- app/javascript/flavours/glitch/styles/components/modal.scss | 4 +--- app/javascript/flavours/glitch/styles/statuses.scss | 7 +++---- 3 files changed, 7 insertions(+), 9 deletions(-) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/features/ui/components/boost_modal.js b/app/javascript/flavours/glitch/features/ui/components/boost_modal.js index 8092e862f..12ad426c8 100644 --- a/app/javascript/flavours/glitch/features/ui/components/boost_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/boost_modal.js @@ -78,9 +78,10 @@ class BoostModal extends ImmutablePureComponent {
- + + +
-
diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss index 85f216887..7abe8818b 100644 --- a/app/javascript/flavours/glitch/styles/components/modal.scss +++ b/app/javascript/flavours/glitch/styles/components/modal.scss @@ -427,10 +427,8 @@ .status__visibility-icon { color: $dark-text-color; - float: right; font-size: 14px; - margin-left: 4px; - margin-right: 4px; + padding: 0 4px; } .status__display-name { diff --git a/app/javascript/flavours/glitch/styles/statuses.scss b/app/javascript/flavours/glitch/styles/statuses.scss index 982a1ab9a..58f74f954 100644 --- a/app/javascript/flavours/glitch/styles/statuses.scss +++ b/app/javascript/flavours/glitch/styles/statuses.scss @@ -201,19 +201,18 @@ display: initial; } - .status__relative-time, - .status__visibility-icon { + .status__relative-time { color: $dark-text-color; float: right; font-size: 14px; width: auto; margin: initial; padding: initial; + padding-bottom: 1px; } .status__visibility-icon { - margin-left: 4px; - margin-right: 4px; + padding: 0 4px; } .status__info .status__display-name { -- cgit From f5df3d1ae25846bb4f651c531c5e5c9bffebeaae Mon Sep 17 00:00:00 2001 From: mayaeh Date: Tue, 27 Oct 2020 21:34:02 +0900 Subject: [Glitch] Fix width of content text fluctuating over time Port 2ae751f19d48c12e70a445ce1d01149866b56ce8 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/styles/components/status.scss | 1 + 1 file changed, 1 insertion(+) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/styles/components/status.scss b/app/javascript/flavours/glitch/styles/components/status.scss index 554ea8cd5..94b9a1e99 100644 --- a/app/javascript/flavours/glitch/styles/components/status.scss +++ b/app/javascript/flavours/glitch/styles/components/status.scss @@ -55,6 +55,7 @@ font-weight: 400; overflow: visible; padding-top: 5px; + clear: both; &:focus { outline: 0; -- cgit From 40af1cf65bdbe9e6ef5f480b6e03cb1be7db5774 Mon Sep 17 00:00:00 2001 From: Mashiro Date: Tue, 3 Nov 2020 04:16:38 +0800 Subject: [Glitch] Add expand/compress image button on image view box Port 6a2db10f767879b9072b6c020ebadac4f985ed34 to glitch-soc Signed-off-by: Thibaut Girka --- .../glitch/features/ui/components/image_loader.js | 4 + .../glitch/features/ui/components/media_modal.js | 24 +- .../features/ui/components/zoomable_image.js | 299 +++++++++++++++++++-- .../flavours/glitch/styles/components/index.scss | 14 + .../flavours/glitch/styles/components/modal.scss | 15 ++ 5 files changed, 335 insertions(+), 21 deletions(-) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/features/ui/components/image_loader.js b/app/javascript/flavours/glitch/features/ui/components/image_loader.js index 5e1cf75af..c6f16a792 100644 --- a/app/javascript/flavours/glitch/features/ui/components/image_loader.js +++ b/app/javascript/flavours/glitch/features/ui/components/image_loader.js @@ -13,6 +13,7 @@ export default class ImageLoader extends React.PureComponent { width: PropTypes.number, height: PropTypes.number, onClick: PropTypes.func, + zoomButtonHidden: PropTypes.bool, } static defaultProps = { @@ -151,6 +152,9 @@ export default class ImageLoader extends React.PureComponent { alt={alt} src={src} onClick={onClick} + width={width} + height={height} + zoomButtonHidden={this.props.zoomButtonHidden} /> )}
diff --git a/app/javascript/flavours/glitch/features/ui/components/media_modal.js b/app/javascript/flavours/glitch/features/ui/components/media_modal.js index aa6554107..e37df7208 100644 --- a/app/javascript/flavours/glitch/features/ui/components/media_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/media_modal.js @@ -35,23 +35,39 @@ class MediaModal extends ImmutablePureComponent { state = { index: null, navigationHidden: false, + zoomButtonHidden: false, }; handleSwipe = (index) => { this.setState({ index: index % this.props.media.size }); } + handleTransitionEnd = () => { + this.setState({ + zoomButtonHidden: false, + }); + } + handleNextClick = () => { - this.setState({ index: (this.getIndex() + 1) % this.props.media.size }); + this.setState({ + index: (this.getIndex() + 1) % this.props.media.size, + zoomButtonHidden: true, + }); } handlePrevClick = () => { - this.setState({ index: (this.props.media.size + this.getIndex() - 1) % this.props.media.size }); + this.setState({ + index: (this.props.media.size + this.getIndex() - 1) % this.props.media.size, + zoomButtonHidden: true, + }); } handleChangeIndex = (e) => { const index = Number(e.currentTarget.getAttribute('data-index')); - this.setState({ index: index % this.props.media.size }); + this.setState({ + index: index % this.props.media.size, + zoomButtonHidden: true, + }); } handleKeyDown = (e) => { @@ -128,6 +144,7 @@ class MediaModal extends ImmutablePureComponent { alt={image.get('description')} key={image.get('url')} onClick={this.toggleNavigation} + zoomButtonHidden={this.state.zoomButtonHidden} /> ); } else if (image.get('type') === 'video') { @@ -191,6 +208,7 @@ class MediaModal extends ImmutablePureComponent { style={swipeableViewsStyle} containerStyle={containerStyle} onChangeIndex={this.handleSwipe} + onTransitionEnd={this.handleTransitionEnd} index={index} > {content} diff --git a/app/javascript/flavours/glitch/features/ui/components/zoomable_image.js b/app/javascript/flavours/glitch/features/ui/components/zoomable_image.js index 3f6562bc9..004913480 100644 --- a/app/javascript/flavours/glitch/features/ui/components/zoomable_image.js +++ b/app/javascript/flavours/glitch/features/ui/components/zoomable_image.js @@ -1,8 +1,16 @@ import React from 'react'; import PropTypes from 'prop-types'; +import IconButton from 'flavours/glitch/components/icon_button'; +import { defineMessages, injectIntl } from 'react-intl'; + +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 MAX_SCALE = 4; +const NAV_BAR_HEIGHT = 66; const getMidpoint = (p1, p2) => ({ x: (p1.clientX + p2.clientX) / 2, @@ -14,7 +22,77 @@ const getDistance = (p1, p2) => const clamp = (min, max, value) => Math.min(max, Math.max(min, value)); -export default class ZoomableImage extends React.PureComponent { +// Normalizing mousewheel speed across browsers +// copy from: https://github.com/facebookarchive/fixed-data-table/blob/master/src/vendor_upstream/dom/normalizeWheel.js +const normalizeWheel = event => { + // Reasonable defaults + const PIXEL_STEP = 10; + const LINE_HEIGHT = 40; + const PAGE_HEIGHT = 800; + + let sX = 0, + sY = 0, // spinX, spinY + pX = 0, + pY = 0; // pixelX, pixelY + + // Legacy + if ('detail' in event) { + sY = event.detail; + } + if ('wheelDelta' in event) { + sY = -event.wheelDelta / 120; + } + if ('wheelDeltaY' in event) { + sY = -event.wheelDeltaY / 120; + } + if ('wheelDeltaX' in event) { + sX = -event.wheelDeltaX / 120; + } + + // side scrolling on FF with DOMMouseScroll + if ('axis' in event && event.axis === event.HORIZONTAL_AXIS) { + sX = sY; + sY = 0; + } + + pX = sX * PIXEL_STEP; + pY = sY * PIXEL_STEP; + + if ('deltaY' in event) { + pY = event.deltaY; + } + if ('deltaX' in event) { + pX = event.deltaX; + } + + if ((pX || pY) && event.deltaMode) { + if (event.deltaMode === 1) { // delta in LINE units + pX *= LINE_HEIGHT; + pY *= LINE_HEIGHT; + } else { // delta in PAGE units + pX *= PAGE_HEIGHT; + pY *= PAGE_HEIGHT; + } + } + + // Fall-back if spin cannot be determined + if (pX && !sX) { + sX = (pX < 1) ? -1 : 1; + } + if (pY && !sY) { + sY = (pY < 1) ? -1 : 1; + } + + return { + spinX: sX, + spinY: sY, + pixelX: pX, + pixelY: pY, + }; +}; + +export default @injectIntl +class ZoomableImage extends React.PureComponent { static propTypes = { alt: PropTypes.string, @@ -22,6 +100,8 @@ export default class ZoomableImage extends React.PureComponent { width: PropTypes.number, height: PropTypes.number, onClick: PropTypes.func, + zoomButtonHidden: PropTypes.bool, + intl: PropTypes.object.isRequired, } static defaultProps = { @@ -32,6 +112,22 @@ export default class ZoomableImage extends React.PureComponent { state = { scale: MIN_SCALE, + zoomMatrix: { + type: null, // 'full-width' 'full-height' + rate: null, // full screen scale rate + clientWidth: null, + clientHeight: null, + offsetWidth: null, + offsetHeight: null, + clientHeightFixed: null, + scrollTop: null, + scrollLeft: null, + }, + zoomState: 'expand', // 'expand' 'compress' + navigationHidden: false, + dragPosition: { top: 0, left: 0, x: 0, y: 0 }, + dragged: false, + lockScroll: { x: 0, y: 0 }, } removers = []; @@ -49,17 +145,101 @@ export default class ZoomableImage extends React.PureComponent { // https://www.chromestatus.com/features/5093566007214080 this.container.addEventListener('touchmove', handler, { passive: false }); this.removers.push(() => this.container.removeEventListener('touchend', handler)); + + handler = this.mouseDownHandler; + this.container.addEventListener('mousedown', handler); + this.removers.push(() => this.container.removeEventListener('mousedown', handler)); + + handler = this.mouseWheelHandler; + this.container.addEventListener('wheel', handler); + this.removers.push(() => this.container.removeEventListener('wheel', handler)); + // Old Chrome + this.container.addEventListener('mousewheel', handler); + this.removers.push(() => this.container.removeEventListener('mousewheel', handler)); + // Old Firefox + this.container.addEventListener('DOMMouseScroll', handler); + this.removers.push(() => this.container.removeEventListener('DOMMouseScroll', handler)); + + this.initZoomMatrix(); } componentWillUnmount () { this.removeEventListeners(); } + componentDidUpdate () { + if (this.props.zoomButtonHidden) { + this.setState({ scale: MIN_SCALE }, () => { + this.container.scrollLeft = 0; + this.container.scrollTop = 0; + }); + } + + this.setState({ zoomState: this.state.scale >= this.state.zoomMatrix.rate ? 'compress' : 'expand' }); + + if (this.state.scale === 1) { + this.container.style.removeProperty('cursor'); + } + } + removeEventListeners () { this.removers.forEach(listeners => listeners()); this.removers = []; } + mouseWheelHandler = e => { + e.preventDefault(); + + const event = normalizeWheel(e); + + if (this.state.zoomMatrix.type === 'full-width') { + // full width, scroll vertical + this.container.scrollTop = this.container.scrollTop + event.pixelY; + } else { + // full height, scroll horizontal + this.container.scrollLeft = this.container.scrollLeft + event.pixelY; + } + } + + mouseDownHandler = e => { + this.container.style.cursor = 'grabbing'; + this.container.style.userSelect = 'none'; + + this.setState({ dragPosition: { + left: this.container.scrollLeft, + top: this.container.scrollTop, + // Get the current mouse position + x: e.clientX, + y: e.clientY, + } }); + + this.image.addEventListener('mousemove', this.mouseMoveHandler); + this.image.addEventListener('mouseup', this.mouseUpHandler); + } + + mouseMoveHandler = e => { + const dx = e.clientX - this.state.dragPosition.x; + const dy = e.clientY - this.state.dragPosition.y; + + if ((this.state.dragPosition.left - dx) >= this.state.lockScroll.x) { + this.container.scrollLeft = this.state.dragPosition.left - dx; + } + + if ((this.state.dragPosition.top - dy) >= this.state.lockScroll.y) { + this.container.scrollTop = this.state.dragPosition.top - dy; + } + + this.setState({ dragged: true }); + } + + mouseUpHandler = () => { + this.container.style.cursor = 'grab'; + this.container.style.removeProperty('user-select'); + + this.image.removeEventListener('mousemove', this.mouseMoveHandler); + this.image.removeEventListener('mouseup', this.mouseUpHandler); + } + handleTouchStart = e => { if (e.touches.length !== 2) return; @@ -80,7 +260,8 @@ export default class ZoomableImage extends React.PureComponent { const distance = getDistance(...e.touches); const midpoint = getMidpoint(...e.touches); - const scale = clamp(MIN_SCALE, MAX_SCALE, this.state.scale * distance / this.lastDistance); + const _MAX_SCALE = Math.max(MAX_SCALE, this.state.zoomMatrix.rate); + const scale = clamp(MIN_SCALE, _MAX_SCALE, this.state.scale * distance / this.lastDistance); this.zoom(scale, midpoint); @@ -110,8 +291,72 @@ export default class ZoomableImage extends React.PureComponent { handleClick = e => { // don't propagate event to MediaModal e.stopPropagation(); + const dragged = this.state.dragged; + this.setState({ dragged: false }); + if (dragged) return; const handler = this.props.onClick; if (handler) handler(); + this.setState({ navigationHidden: !this.state.navigationHidden }); + } + + handleMouseDown = e => { + e.preventDefault(); + } + + initZoomMatrix = () => { + const { width, height } = this.props; + const { clientWidth, clientHeight } = this.container; + const { offsetWidth, offsetHeight } = this.image; + const clientHeightFixed = clientHeight - NAV_BAR_HEIGHT; + + const type = width/height < clientWidth / clientHeightFixed ? 'full-width' : 'full-height'; + const rate = type === 'full-width' ? clientWidth / offsetWidth : clientHeightFixed / offsetHeight; + const scrollTop = type === 'full-width' ? (clientHeight - offsetHeight) / 2 - NAV_BAR_HEIGHT : (clientHeightFixed - offsetHeight) / 2; + const scrollLeft = (clientWidth - offsetWidth) / 2; + + this.setState({ + zoomMatrix: { + type: type, + rate: rate, + clientWidth: clientWidth, + clientHeight: clientHeight, + offsetWidth: offsetWidth, + offsetHeight: offsetHeight, + clientHeightFixed: clientHeightFixed, + scrollTop: scrollTop, + scrollLeft: scrollLeft, + }, + }); + } + + handleZoomClick = e => { + e.preventDefault(); + e.stopPropagation(); + + const { scale, zoomMatrix } = this.state; + + if ( scale >= zoomMatrix.rate ) { + this.setState({ scale: MIN_SCALE }, () => { + this.container.scrollLeft = 0; + this.container.scrollTop = 0; + this.setState({ lockScroll: { + x: 0, + y: 0, + } }); + }); + } else { + this.setState({ scale: zoomMatrix.rate }, () => { + this.container.scrollLeft = zoomMatrix.scrollLeft; + this.container.scrollTop = zoomMatrix.scrollTop; + this.setState({ lockScroll: { + x: zoomMatrix.scrollLeft, + y: zoomMatrix.scrollTop, + } }); + }); + } + + this.container.style.cursor = 'grab'; + this.container.style.removeProperty('user-select'); } setContainerRef = c => { @@ -123,29 +368,47 @@ export default class ZoomableImage extends React.PureComponent { } render () { - const { alt, src } = this.props; + const { alt, src, width, height, intl } = this.props; const { scale } = this.state; const overflow = scale === 1 ? 'hidden' : 'scroll'; + const zoomButtonSshouldHide = !this.state.navigationHidden && !this.props.zoomButtonHidden ? '' : 'media-modal__zoom-button--hidden'; + const zoomButtonTitle = this.state.zoomState === 'compress' ? intl.formatMessage(messages.compress) : intl.formatMessage(messages.expand); return ( -
- {alt} + -
+
+ {alt} +
+ ); } diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss index 0614278e2..3e67754c5 100644 --- a/app/javascript/flavours/glitch/styles/components/index.scss +++ b/app/javascript/flavours/glitch/styles/components/index.scss @@ -425,6 +425,20 @@ align-items: center; justify-content: center; flex-direction: column; + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE 10+ */ + + * { + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE 10+ */ + } + + &::-webkit-scrollbar, + *::-webkit-scrollbar { + width: 0; + height: 0; + background: transparent; /* Chrome/Safari/Webkit */ + } .image-loader__preview-canvas { max-width: $media-modal-media-max-width; diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss index 7abe8818b..bc0965864 100644 --- a/app/javascript/flavours/glitch/styles/components/modal.scss +++ b/app/javascript/flavours/glitch/styles/components/modal.scss @@ -40,6 +40,21 @@ z-index: 9999; } +.media-modal__zoom-button { + position: absolute; + right: 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, .error-modal, .embed-modal { -- cgit From 0aeb833317de7ad8962ebde113836585cfe6b33d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 11 Nov 2020 05:36:29 +0100 Subject: [Glitch] Add button to dismiss desktop notifications permissions banner Port 4790a126bebddd83cbaf1a8436611536dcc417a0 to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/actions/notifications.js | 9 +++++++-- .../components/notifications_permission_banner.js | 23 +++++++++++++++++++--- .../picture_in_picture/components/header.js | 11 +++++++++-- .../flavours/glitch/reducers/notifications.js | 3 +++ .../flavours/glitch/styles/components/columns.scss | 7 +++++++ 5 files changed, 46 insertions(+), 7 deletions(-) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js index eb7087027..7273191b2 100644 --- a/app/javascript/flavours/glitch/actions/notifications.js +++ b/app/javascript/flavours/glitch/actions/notifications.js @@ -50,8 +50,9 @@ export const NOTIFICATIONS_SET_VISIBILITY = 'NOTIFICATIONS_SET_VISIBILITY'; export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ'; -export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT'; -export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION'; +export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT'; +export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION'; +export const NOTIFICATIONS_DISMISS_BROWSER_PERMISSION = 'NOTIFICATIONS_DISMISS_BROWSER_PERMISSION'; defineMessages({ mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' }, @@ -371,3 +372,7 @@ export function setBrowserPermission (value) { value, }; } + +export const dismissBrowserPermission = () => ({ + type: NOTIFICATIONS_DISMISS_BROWSER_PERMISSION, +}); diff --git a/app/javascript/flavours/glitch/features/notifications/components/notifications_permission_banner.js b/app/javascript/flavours/glitch/features/notifications/components/notifications_permission_banner.js index 8e77f5a03..73fc05dea 100644 --- a/app/javascript/flavours/glitch/features/notifications/components/notifications_permission_banner.js +++ b/app/javascript/flavours/glitch/features/notifications/components/notifications_permission_banner.js @@ -1,25 +1,42 @@ import React from 'react'; import Icon from 'flavours/glitch/components/icon'; import Button from 'flavours/glitch/components/button'; -import { requestBrowserPermission } from 'flavours/glitch/actions/notifications'; +import IconButton from 'flavours/glitch/components/icon_button'; +import { requestBrowserPermission, dismissBrowserPermission } from 'flavours/glitch/actions/notifications'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; -export default @connect(() => {}) +const messages = defineMessages({ + close: { id: 'lightbox.close', defaultMessage: 'Close' }, +}); + +export default @connect() +@injectIntl class NotificationsPermissionBanner extends React.PureComponent { static propTypes = { dispatch: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, }; handleClick = () => { this.props.dispatch(requestBrowserPermission()); } + handleClose = () => { + this.props.dispatch(dismissBrowserPermission()); + } + render () { + const { intl } = this.props; + return (
+
+ +
+

}} />

diff --git a/app/javascript/flavours/glitch/features/picture_in_picture/components/header.js b/app/javascript/flavours/glitch/features/picture_in_picture/components/header.js index 24adcde25..28526ca88 100644 --- a/app/javascript/flavours/glitch/features/picture_in_picture/components/header.js +++ b/app/javascript/flavours/glitch/features/picture_in_picture/components/header.js @@ -7,12 +7,18 @@ import IconButton from 'flavours/glitch/components/icon_button'; import { Link } from 'react-router-dom'; import Avatar from 'flavours/glitch/components/avatar'; import DisplayName from 'flavours/glitch/components/display_name'; +import { defineMessages, injectIntl } from 'react-intl'; + +const messages = defineMessages({ + close: { id: 'lightbox.close', defaultMessage: 'Close' }, +}); const mapStateToProps = (state, { accountId }) => ({ account: state.getIn(['accounts', accountId]), }); export default @connect(mapStateToProps) +@injectIntl class Header extends ImmutablePureComponent { static propTypes = { @@ -20,10 +26,11 @@ class Header extends ImmutablePureComponent { statusId: PropTypes.string.isRequired, account: ImmutablePropTypes.map.isRequired, onClose: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, }; render () { - const { account, statusId, onClose } = this.props; + const { account, statusId, onClose, intl } = this.props; return (
@@ -32,7 +39,7 @@ class Header extends ImmutablePureComponent { - +
); } diff --git a/app/javascript/flavours/glitch/reducers/notifications.js b/app/javascript/flavours/glitch/reducers/notifications.js index b4c5ef71a..c630cc7e3 100644 --- a/app/javascript/flavours/glitch/reducers/notifications.js +++ b/app/javascript/flavours/glitch/reducers/notifications.js @@ -19,6 +19,7 @@ import { NOTIFICATIONS_MARK_AS_READ, NOTIFICATIONS_SET_BROWSER_SUPPORT, NOTIFICATIONS_SET_BROWSER_PERMISSION, + NOTIFICATIONS_DISMISS_BROWSER_PERMISSION, } from 'flavours/glitch/actions/notifications'; import { ACCOUNT_BLOCK_SUCCESS, @@ -283,6 +284,8 @@ export default function notifications(state = initialState, action) { return state.set('browserSupport', action.value); case NOTIFICATIONS_SET_BROWSER_PERMISSION: return state.set('browserPermission', action.value); + case NOTIFICATIONS_DISMISS_BROWSER_PERMISSION: + return state.set('browserPermission', 'denied'); case NOTIFICATION_MARK_FOR_DELETE: return markForDelete(state, action.id, action.yes); diff --git a/app/javascript/flavours/glitch/styles/components/columns.scss b/app/javascript/flavours/glitch/styles/components/columns.scss index be32ae52e..2550f50f4 100644 --- a/app/javascript/flavours/glitch/styles/components/columns.scss +++ b/app/javascript/flavours/glitch/styles/components/columns.scss @@ -702,6 +702,13 @@ flex-direction: column; align-items: center; justify-content: center; + position: relative; + + &__close { + position: absolute; + top: 10px; + right: 10px; + } h2 { font-size: 16px; -- cgit