From ccf4f3240ae80f4b1410d816f03d0bef33062a71 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 27 Apr 2019 03:24:09 +0200 Subject: [Glitch] Add blurhash Port front-end changes from fba96c808d25d2fc35ec63ee6745a1e55a95d707 to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/styles/components/index.scss | 44 +++++++++++++++++++--- .../flavours/glitch/styles/components/media.scss | 17 +++++++++ .../flavours/glitch/styles/components/status.scss | 9 ++--- 3 files changed, 60 insertions(+), 10 deletions(-) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss index b098676b0..b323305cc 100644 --- a/app/javascript/flavours/glitch/styles/components/index.scss +++ b/app/javascript/flavours/glitch/styles/components/index.scss @@ -1066,15 +1066,49 @@ } .spoiler-button { - display: none; - left: 4px; + top: 0; + left: 0; + width: 100%; + height: 100%; position: absolute; - text-shadow: 0 1px 1px $base-shadow-color, 1px 0 1px $base-shadow-color; - top: 4px; z-index: 100; - &.spoiler-button--visible { + &--minified { + display: block; + left: 4px; + top: 4px; + width: auto; + height: auto; + } + + &--hidden { + display: none; + } + + &__overlay { display: block; + background: transparent; + width: 100%; + height: 100%; + border: 0; + + &__label { + display: inline-block; + background: rgba($base-overlay-background, 0.5); + border-radius: 8px; + padding: 8px 12px; + color: $primary-text-color; + font-weight: 500; + font-size: 14px; + } + + &:hover, + &:focus, + &:active { + .spoiler-button__overlay__label { + background: rgba($base-overlay-background, 0.8); + } + } } } diff --git a/app/javascript/flavours/glitch/styles/components/media.scss b/app/javascript/flavours/glitch/styles/components/media.scss index fabef2a56..0393a3886 100644 --- a/app/javascript/flavours/glitch/styles/components/media.scss +++ b/app/javascript/flavours/glitch/styles/components/media.scss @@ -117,6 +117,8 @@ text-decoration: none; color: $secondary-text-color; line-height: 0; + position: relative; + z-index: 1; &, img { @@ -131,6 +133,21 @@ } } +.media-gallery__preview { + width: 100%; + height: 100%; + object-fit: cover; + position: absolute; + top: 0; + left: 0; + z-index: 0; + background: $base-overlay-background; + + &--hidden { + display: none; + } +} + .media-gallery__gifv { height: 100%; overflow: hidden; diff --git a/app/javascript/flavours/glitch/styles/components/status.scss b/app/javascript/flavours/glitch/styles/components/status.scss index b656f0baf..fb031258f 100644 --- a/app/javascript/flavours/glitch/styles/components/status.scss +++ b/app/javascript/flavours/glitch/styles/components/status.scss @@ -705,7 +705,7 @@ & > div { background: rgba($base-shadow-color, 0.6); - border-radius: 4px; + border-radius: 8px; padding: 12px 9px; flex: 0 0 auto; display: flex; @@ -716,19 +716,18 @@ button, a { display: inline; - color: $primary-text-color; + color: $secondary-text-color; background: transparent; border: 0; - padding: 0 5px; + padding: 0 8px; text-decoration: none; - opacity: 0.6; font-size: 18px; line-height: 18px; &:hover, &:active, &:focus { - opacity: 1; + color: $primary-text-color; } } -- cgit From 373dd1fdf167977c97041059cf009a1331132d28 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sat, 4 May 2019 18:18:15 +0200 Subject: Minor CSS fixes --- app/javascript/flavours/glitch/styles/components/index.scss | 3 ++- app/javascript/flavours/glitch/styles/components/sensitive.scss | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss index b323305cc..788bb2e0e 100644 --- a/app/javascript/flavours/glitch/styles/components/index.scss +++ b/app/javascript/flavours/glitch/styles/components/index.scss @@ -1074,11 +1074,12 @@ z-index: 100; &--minified { - display: block; + display: flex; left: 4px; top: 4px; width: auto; height: auto; + align-items: center; } &--hidden { diff --git a/app/javascript/flavours/glitch/styles/components/sensitive.scss b/app/javascript/flavours/glitch/styles/components/sensitive.scss index b0a7dfe03..44b7ec981 100644 --- a/app/javascript/flavours/glitch/styles/components/sensitive.scss +++ b/app/javascript/flavours/glitch/styles/components/sensitive.scss @@ -9,13 +9,12 @@ } .sensitive-marker { - margin: 0 3px; border-radius: 2px; padding: 2px 6px; color: rgba($primary-text-color, 0.8); background: rgba($base-overlay-background, 0.5); font-size: 12px; - line-height: 15px; + line-height: 18px; text-transform: uppercase; opacity: .9; transition: opacity .1s ease; -- cgit From a5da59f140a2a8fb2d3f480cdd87964d0beff103 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 2 May 2019 08:34:32 +0200 Subject: [Glitch] Change account gallery in web UI Port 3f143606faa6181ff2745b6bd29ac8ea075088bf to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/components/media_gallery.js | 2 +- .../account_gallery/components/media_item.js | 160 +++++++++++++++------ .../glitch/features/account_gallery/index.js | 67 +++++---- .../glitch/styles/components/accounts.scss | 59 ++------ .../flavours/glitch/styles/components/media.scss | 1 + 5 files changed, 168 insertions(+), 121 deletions(-) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/components/media_gallery.js b/app/javascript/flavours/glitch/components/media_gallery.js index d1dde45b1..ab1cccc60 100644 --- a/app/javascript/flavours/glitch/components/media_gallery.js +++ b/app/javascript/flavours/glitch/components/media_gallery.js @@ -177,7 +177,7 @@ class Item extends React.PureComponent { if (attachment.get('type') === 'unknown') { return ( diff --git a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js b/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js index 89778e123..cc35097a7 100644 --- a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js +++ b/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js @@ -1,69 +1,141 @@ import React from 'react'; +import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; -import Permalink from 'flavours/glitch/components/permalink'; -import { displayMedia } from 'flavours/glitch/util/initial_state'; +import { autoPlayGif, displayMedia } from 'flavours/glitch/util/initial_state'; +import classNames from 'classnames'; +import { decode } from 'blurhash'; +import { isIOS } from 'flavours/glitch/util/is_mobile'; export default class MediaItem extends ImmutablePureComponent { static propTypes = { - media: ImmutablePropTypes.map.isRequired, + attachment: ImmutablePropTypes.map.isRequired, + displayWidth: PropTypes.number.isRequired, + onOpenMedia: PropTypes.func.isRequired, }; state = { - visible: displayMedia !== 'hide_all' && !this.props.media.getIn(['status', 'sensitive']) || displayMedia === 'show_all', + visible: displayMedia !== 'hide_all' && !this.props.attachment.getIn(['status', 'sensitive']) || displayMedia === 'show_all', + loaded: false, }; - handleClick = () => { - if (!this.state.visible) { - this.setState({ visible: true }); - return true; + componentDidMount () { + if (this.props.attachment.get('blurhash')) { + this._decode(); } + } - return false; + componentDidUpdate (prevProps) { + if (prevProps.attachment.get('blurhash') !== this.props.attachment.get('blurhash') && this.props.attachment.get('blurhash')) { + this._decode(); + } } - render () { - const { media } = this.props; - const { visible } = this.state; - const status = media.get('status'); - const focusX = media.getIn(['meta', 'focus', 'x']); - const focusY = media.getIn(['meta', 'focus', 'y']); - const x = ((focusX / 2) + .5) * 100; - const y = ((focusY / -2) + .5) * 100; - const style = {}; - - let label, icon, title; - - if (media.get('type') === 'gifv') { - label = GIF; + _decode () { + const hash = this.props.attachment.get('blurhash'); + const pixels = decode(hash, 32, 32); + + if (pixels) { + const ctx = this.canvas.getContext('2d'); + const imageData = new ImageData(pixels, 32, 32); + + ctx.putImageData(imageData, 0, 0); + } + } + + setCanvasRef = c => { + this.canvas = c; + } + + handleImageLoad = () => { + this.setState({ loaded: true }); + } + + handleMouseEnter = e => { + if (this.hoverToPlay()) { + e.target.play(); + } + } + + handleMouseLeave = e => { + if (this.hoverToPlay()) { + e.target.pause(); + e.target.currentTime = 0; } + } + + hoverToPlay () { + return !autoPlayGif && ['gifv', 'video'].indexOf(this.props.attachment.get('type')) !== -1; + } + + handleClick = e => { + if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { + e.preventDefault(); + + if (this.state.visible) { + this.props.onOpenMedia(this.props.attachment); + } else { + this.setState({ visible: true }); + } + } + } + + render () { + const { attachment, displayWidth } = this.props; + const { visible, loaded } = this.state; + + const width = `${Math.floor((displayWidth - 4) / 3) - 4}px`; + const height = width; + const status = attachment.get('status'); + + let thumbnail = ''; + + if (attachment.get('type') === 'unknown') { + // Skip + } else if (attachment.get('type') === 'image') { + const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0; + const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0; + const x = ((focusX / 2) + .5) * 100; + const y = ((focusY / -2) + .5) * 100; + + thumbnail = ( + {attachment.get('description')} + ); + } else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) { + const autoPlay = !isIOS() && autoPlayGif; - if (visible) { - style.backgroundImage = `url(${media.get('preview_url')})`; - style.backgroundPosition = `${x}% ${y}%`; - title = media.get('description'); - } else { - icon = ( - - - + thumbnail = ( +
+
); - title = status.get('spoiler_text') || media.get('description'); } return ( -
- - {icon} - {label} - + ); } diff --git a/app/javascript/flavours/glitch/features/account_gallery/index.js b/app/javascript/flavours/glitch/features/account_gallery/index.js index 3b1af108f..264aff261 100644 --- a/app/javascript/flavours/glitch/features/account_gallery/index.js +++ b/app/javascript/flavours/glitch/features/account_gallery/index.js @@ -14,12 +14,13 @@ import HeaderContainer from 'flavours/glitch/features/account_timeline/container import { ScrollContainer } from 'react-router-scroll-4'; import LoadMore from 'flavours/glitch/components/load_more'; import MissingIndicator from 'flavours/glitch/components/missing_indicator'; +import { openModal } from 'flavours/glitch/actions/modal'; const mapStateToProps = (state, props) => ({ isAccount: !!state.getIn(['accounts', props.params.accountId]), - medias: getAccountGallery(state, props.params.accountId), + attachments: getAccountGallery(state, props.params.accountId), isLoading: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'isLoading']), - hasMore: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'hasMore']), + hasMore: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'hasMore']), }); class LoadMoreMedia extends ImmutablePureComponent { @@ -50,12 +51,16 @@ export default class AccountGallery extends ImmutablePureComponent { static propTypes = { params: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, - medias: ImmutablePropTypes.list.isRequired, + attachments: ImmutablePropTypes.list.isRequired, isLoading: PropTypes.bool, hasMore: PropTypes.bool, isAccount: PropTypes.bool, }; + state = { + width: 323, + }; + componentDidMount () { this.props.dispatch(fetchAccount(this.props.params.accountId)); this.props.dispatch(expandAccountMediaTimeline(this.props.params.accountId)); @@ -74,11 +79,11 @@ export default class AccountGallery extends ImmutablePureComponent { handleScrollToBottom = () => { if (this.props.hasMore) { - this.handleLoadMore(this.props.medias.size > 0 ? this.props.medias.last().getIn(['status', 'id']) : undefined); + this.handleLoadMore(this.props.attachments.size > 0 ? this.props.attachments.last().getIn(['status', 'id']) : undefined); } } - handleScroll = (e) => { + handleScroll = e => { const { scrollTop, scrollHeight, clientHeight } = e.target; const offset = scrollHeight - scrollTop - clientHeight; @@ -91,7 +96,7 @@ export default class AccountGallery extends ImmutablePureComponent { this.props.dispatch(expandAccountMediaTimeline(this.props.params.accountId, { maxId })); }; - handleLoadOlder = (e) => { + handleLoadOlder = e => { e.preventDefault(); this.handleScrollToBottom(); } @@ -101,12 +106,30 @@ export default class AccountGallery extends ImmutablePureComponent { return !(location.state && location.state.mastodonModalOpen); } - setRef = c => { + setColumnRef = c => { this.column = c; } + handleOpenMedia = attachment => { + if (attachment.get('type') === 'video') { + this.props.dispatch(openModal('VIDEO', { media: attachment })); + } else { + const media = attachment.getIn(['status', 'media_attachments']); + const index = media.findIndex(x => x.get('id') === attachment.get('id')); + + this.props.dispatch(openModal('MEDIA', { media, index })); + } + } + + handleRef = c => { + if (c) { + this.setState({ width: c.offsetWidth }); + } + } + render () { - const { medias, isLoading, hasMore, isAccount } = this.props; + const { attachments, isLoading, hasMore, isAccount } = this.props; + const { width } = this.state; if (!isAccount) { return ( @@ -116,9 +139,7 @@ export default class AccountGallery extends ImmutablePureComponent { ); } - let loadOlder = null; - - if (!medias && isLoading) { + if (!attachments && isLoading) { return ( @@ -126,35 +147,31 @@ export default class AccountGallery extends ImmutablePureComponent { ); } - if (hasMore && !(isLoading && medias.size === 0)) { + let loadOlder = null; + + if (hasMore && !(isLoading && attachments.size === 0)) { loadOlder = ; } return ( - +
-
- {medias.map((media, index) => media === null ? ( - 0 ? medias.getIn(index - 1, 'id') : null} - onLoadMore={this.handleLoadMore} - /> +
+ {attachments.map((attachment, index) => attachment === null ? ( + 0 ? attachments.getIn(index - 1, 'id') : null} onLoadMore={this.handleLoadMore} /> ) : ( - + ))} + {loadOlder}
- {isLoading && medias.size === 0 && ( + {isLoading && attachments.size === 0 && (
diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss index 00380c575..f753b7efa 100644 --- a/app/javascript/flavours/glitch/styles/components/accounts.scss +++ b/app/javascript/flavours/glitch/styles/components/accounts.scss @@ -331,62 +331,19 @@ .account-gallery__container { display: flex; - justify-content: center; flex-wrap: wrap; - padding: 2px; + justify-content: center; + padding: 4px 2px; } .account-gallery__item { - flex-grow: 1; - width: 50%; - overflow: hidden; + border: none; + box-sizing: border-box; + display: block; position: relative; - - &::before { - content: ""; - display: block; - padding-top: 100%; - } - - a { - display: block; - width: calc(100% - 4px); - height: calc(100% - 4px); - margin: 2px; - top: 0; - left: 0; - background-color: $base-overlay-background; - background-size: cover; - background-position: center; - position: absolute; - color: $ui-primary-color; - text-decoration: none; - border-radius: 4px; - - &:hover, - &:active, - &:focus { - outline: 0; - color: $ui-secondary-color; - - &::before { - content: ""; - display: block; - width: 100%; - height: 100%; - background: rgba($base-overlay-background, 0.3); - border-radius: 4px; - } - } - } - - &__icons { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - font-size: 24px; - } + border-radius: 4px; + overflow: hidden; + margin: 2px; } .notification__filter-bar, diff --git a/app/javascript/flavours/glitch/styles/components/media.scss b/app/javascript/flavours/glitch/styles/components/media.scss index 0393a3886..bc241de14 100644 --- a/app/javascript/flavours/glitch/styles/components/media.scss +++ b/app/javascript/flavours/glitch/styles/components/media.scss @@ -58,6 +58,7 @@ pointer-events: none; opacity: 0.9; transition: opacity 0.1s ease; + line-height: 18px; } .media-gallery__gifv { -- cgit From 209c080280f8dbe7dd02fc328841135b8eade15a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 3 May 2019 04:02:55 +0200 Subject: [Glitch] Fix alignment of items in the account gallery in web UI and load more per page Port 967e419f8fa87af74f4bb530d7493c1dde02fca8 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/actions/timelines.js | 2 +- app/javascript/flavours/glitch/styles/components/accounts.scss | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/actions/timelines.js b/app/javascript/flavours/glitch/actions/timelines.js index f218ee06b..cca571583 100644 --- a/app/javascript/flavours/glitch/actions/timelines.js +++ b/app/javascript/flavours/glitch/actions/timelines.js @@ -97,7 +97,7 @@ export const expandCommunityTimeline = ({ maxId, onlyMedia } = {}, done = export const expandDirectTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('direct', '/api/v1/timelines/direct', { max_id: maxId }, done); export const expandAccountTimeline = (accountId, { maxId, withReplies } = {}) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies, max_id: maxId }); export const expandAccountFeaturedTimeline = accountId => expandTimeline(`account:${accountId}:pinned`, `/api/v1/accounts/${accountId}/statuses`, { pinned: true }); -export const expandAccountMediaTimeline = (accountId, { maxId } = {}) => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { max_id: maxId, only_media: true }); +export const expandAccountMediaTimeline = (accountId, { maxId } = {}) => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { max_id: maxId, only_media: true, limit: 40 }); export const expandListTimeline = (id, { maxId } = {}, done = noOp) => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`, { max_id: maxId }, done); export const expandHashtagTimeline = (hashtag, { maxId, tags } = {}, done = noOp) => { diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss index f753b7efa..518eea5fa 100644 --- a/app/javascript/flavours/glitch/styles/components/accounts.scss +++ b/app/javascript/flavours/glitch/styles/components/accounts.scss @@ -332,7 +332,6 @@ .account-gallery__container { display: flex; flex-wrap: wrap; - justify-content: center; padding: 4px 2px; } -- cgit From bc97fd641f1f075e45f920fdc214f355ce16f53d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 3 May 2019 16:16:30 +0200 Subject: [Glitch] Add button to view context to media modal Port eb63217210b0ab85ff1fcca9506d5e7931382a56 to glitch-soc Signed-off-by: Thibaut Girka --- .../glitch/features/account_gallery/index.js | 4 +-- .../glitch/features/ui/components/media_modal.js | 25 +++++++++++-- .../glitch/features/ui/components/video_modal.js | 18 +++++++++- .../flavours/glitch/features/video/index.js | 9 +++-- .../flavours/glitch/styles/components/media.scss | 42 ++++++++++++++++++++++ 5 files changed, 90 insertions(+), 8 deletions(-) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/features/account_gallery/index.js b/app/javascript/flavours/glitch/features/account_gallery/index.js index 264aff261..3e4421306 100644 --- a/app/javascript/flavours/glitch/features/account_gallery/index.js +++ b/app/javascript/flavours/glitch/features/account_gallery/index.js @@ -112,12 +112,12 @@ export default class AccountGallery extends ImmutablePureComponent { handleOpenMedia = attachment => { if (attachment.get('type') === 'video') { - this.props.dispatch(openModal('VIDEO', { media: attachment })); + this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status') })); } else { const media = attachment.getIn(['status', 'media_attachments']); const index = media.findIndex(x => x.get('id') === attachment.get('id')); - this.props.dispatch(openModal('MEDIA', { media, index })); + this.props.dispatch(openModal('MEDIA', { media, index, status: attachment.get('status') })); } } 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 39386ee1c..ce6660480 100644 --- a/app/javascript/flavours/glitch/features/ui/components/media_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/media_modal.js @@ -5,7 +5,7 @@ import PropTypes from 'prop-types'; import Video from 'flavours/glitch/features/video'; import ExtendedVideoPlayer from 'flavours/glitch/components/extended_video_player'; import classNames from 'classnames'; -import { defineMessages, injectIntl } from 'react-intl'; +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import IconButton from 'flavours/glitch/components/icon_button'; import ImmutablePureComponent from 'react-immutable-pure-component'; import ImageLoader from './image_loader'; @@ -19,8 +19,13 @@ const messages = defineMessages({ @injectIntl export default class MediaModal extends ImmutablePureComponent { + static contextTypes = { + router: PropTypes.object, + }; + static propTypes = { media: ImmutablePropTypes.list.isRequired, + status: ImmutablePropTypes.map, index: PropTypes.number.isRequired, onClose: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, @@ -81,8 +86,15 @@ export default class MediaModal extends ImmutablePureComponent { })); }; + handleStatusClick = e => { + if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { + e.preventDefault(); + this.context.router.history.push(`/statuses/${this.props.status.get('id')}`); + } + } + render () { - const { media, intl, onClose } = this.props; + const { media, status, intl, onClose } = this.props; const { navigationHidden } = this.state; const index = this.getIndex(); @@ -186,10 +198,19 @@ export default class MediaModal extends ImmutablePureComponent { {content}
+
+ {leftNav} {rightNav} + + {status && ( +
1 })}> + +
+ )} +
    {pagination}
diff --git a/app/javascript/flavours/glitch/features/ui/components/video_modal.js b/app/javascript/flavours/glitch/features/ui/components/video_modal.js index 8c74d5a13..3f742c260 100644 --- a/app/javascript/flavours/glitch/features/ui/components/video_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/video_modal.js @@ -3,17 +3,32 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import Video from 'flavours/glitch/features/video'; import ImmutablePureComponent from 'react-immutable-pure-component'; +import { FormattedMessage } from 'react-intl'; export default class VideoModal extends ImmutablePureComponent { + static contextTypes = { + router: PropTypes.object, + }; + static propTypes = { media: ImmutablePropTypes.map.isRequired, + status: ImmutablePropTypes.map, time: PropTypes.number, onClose: PropTypes.func.isRequired, }; + handleStatusClick = e => { + if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { + e.preventDefault(); + this.context.router.history.push(`/statuses/${this.props.status.get('id')}`); + } + } + render () { - const { media, time, onClose } = this.props; + const { media, status, time, onClose } = this.props; + + const link = status && ; return (
@@ -24,6 +39,7 @@ export default class VideoModal extends ImmutablePureComponent { src={media.get('url')} startTime={time} onCloseVideo={onClose} + link={link} detailed alt={media.get('description')} /> diff --git a/app/javascript/flavours/glitch/features/video/index.js b/app/javascript/flavours/glitch/features/video/index.js index aad24b1d9..381485802 100644 --- a/app/javascript/flavours/glitch/features/video/index.js +++ b/app/javascript/flavours/glitch/features/video/index.js @@ -106,6 +106,7 @@ export default class Video extends React.PureComponent { intl: PropTypes.object.isRequired, cacheWidth: PropTypes.func, blurhash: PropTypes.string, + link: PropTypes.node, }; state = { @@ -384,7 +385,7 @@ export default class Video extends React.PureComponent { } render () { - const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, letterbox, fullwidth, detailed, sensitive } = this.props; + const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, letterbox, fullwidth, detailed, sensitive, link } = this.props; const { containerWidth, currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state; const progress = (currentTime / duration) * 100; const playerStyle = {}; @@ -487,13 +488,15 @@ export default class Video extends React.PureComponent { />
- {(detailed || fullscreen) && + {(detailed || fullscreen) && ( {formatTime(currentTime)} / {formatTime(duration)} - } + )} + + {link && {link}}
diff --git a/app/javascript/flavours/glitch/styles/components/media.scss b/app/javascript/flavours/glitch/styles/components/media.scss index bc241de14..e5927057e 100644 --- a/app/javascript/flavours/glitch/styles/components/media.scss +++ b/app/javascript/flavours/glitch/styles/components/media.scss @@ -270,6 +270,31 @@ pointer-events: none; } +.media-modal__meta { + text-align: center; + position: absolute; + left: 0; + bottom: 20px; + width: 100%; + pointer-events: none; + + &--shifted { + bottom: 62px; + } + + a { + text-decoration: none; + font-weight: 500; + color: $ui-secondary-color; + + &:hover, + &:focus, + &:active { + text-decoration: underline; + } + } +} + .media-modal__page-dot { display: inline-block; } @@ -519,6 +544,23 @@ } } + &__link { + padding: 2px 10px; + + a { + text-decoration: none; + font-size: 14px; + font-weight: 500; + color: $white; + + &:hover, + &:active, + &:focus { + text-decoration: underline; + } + } + } + &__seek { cursor: pointer; height: 24px; -- cgit From 8e221cd22bf272f7de8c12e06a98bfb7226a4f1c Mon Sep 17 00:00:00 2001 From: ThibG Date: Sat, 4 May 2019 17:39:53 +0200 Subject: [Glitch] Fix transition: all Port 7aa749ab46b53bc5b234332ac35acc09a636fc28 to glitch-soc --- app/javascript/flavours/glitch/styles/admin.scss | 2 ++ app/javascript/flavours/glitch/styles/components/drawer.scss | 1 + app/javascript/flavours/glitch/styles/components/index.scss | 8 ++++++-- app/javascript/flavours/glitch/styles/components/search.scss | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index 05c7821e4..74f91599a 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -50,6 +50,7 @@ $content-width: 840px; color: $darker-text-color; text-decoration: none; transition: all 200ms linear; + transition-property: color, background-color; border-radius: 4px 0 0 4px; i.fa { @@ -60,6 +61,7 @@ $content-width: 840px; color: $primary-text-color; background-color: darken($ui-base-color, 5%); transition: all 100ms linear; + transition-property: color, background-color; } &.selected { diff --git a/app/javascript/flavours/glitch/styles/components/drawer.scss b/app/javascript/flavours/glitch/styles/components/drawer.scss index 41c794790..9f426448f 100644 --- a/app/javascript/flavours/glitch/styles/components/drawer.scss +++ b/app/javascript/flavours/glitch/styles/components/drawer.scss @@ -125,6 +125,7 @@ cursor: default; pointer-events: none; transition: all 100ms linear; + transition-property: color, transform, opacity; } .fa-search { diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss index 788bb2e0e..f12f8b7fa 100644 --- a/app/javascript/flavours/glitch/styles/components/index.scss +++ b/app/javascript/flavours/glitch/styles/components/index.scss @@ -25,6 +25,7 @@ text-decoration: none; text-overflow: ellipsis; transition: all 100ms ease-in; + transition-property: background-color; white-space: nowrap; width: auto; @@ -33,6 +34,7 @@ &:hover { background-color: lighten($ui-highlight-color, 7%); transition: all 200ms ease-out; + transition-property: background-color; } &--destructive { @@ -564,6 +566,7 @@ font-weight: 500; border-bottom: 2px solid lighten($ui-base-color, 8%); transition: all 200ms linear; + transition-property: background; .fa { font-weight: 400; @@ -581,6 +584,7 @@ @include multi-columns('screen and (min-width: 631px)') { background: lighten($ui-base-color, 14%); transition: all 100ms linear; + transition-property: background; } } @@ -664,7 +668,7 @@ padding: 0; border-radius: 30px; background-color: $ui-base-color; - transition: all 0.2s ease; + transition: background-color 0.2s ease; } .react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track { @@ -717,7 +721,6 @@ } .react-toggle-thumb { - transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1) 0ms; position: absolute; top: 1px; left: 1px; @@ -728,6 +731,7 @@ background-color: darken($simple-background-color, 2%); box-sizing: border-box; transition: all 0.25s ease; + transition-property: border-color, left; } .react-toggle--checked .react-toggle-thumb { diff --git a/app/javascript/flavours/glitch/styles/components/search.scss b/app/javascript/flavours/glitch/styles/components/search.scss index 3746fbad2..f59ef019e 100644 --- a/app/javascript/flavours/glitch/styles/components/search.scss +++ b/app/javascript/flavours/glitch/styles/components/search.scss @@ -18,6 +18,7 @@ display: inline-block; opacity: 0; transition: all 100ms linear; + transition-property: transform, opacity; font-size: 18px; width: 18px; height: 18px; -- cgit From b1ab4d5ebe3ccb7d91e55eedd0ad08226358c446 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sat, 4 May 2019 20:06:17 +0200 Subject: Add visibility icon back in media gallery --- .../glitch/features/account_gallery/components/media_item.js | 8 +++++++- app/javascript/flavours/glitch/styles/components/accounts.scss | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js b/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js index f2a661862..026136b2c 100644 --- a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js +++ b/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js @@ -131,11 +131,17 @@ export default class MediaItem extends ImmutablePureComponent { ); } + const icon = ( + + + + ); + return ( ); diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss index 518eea5fa..c0340e3f8 100644 --- a/app/javascript/flavours/glitch/styles/components/accounts.scss +++ b/app/javascript/flavours/glitch/styles/components/accounts.scss @@ -343,6 +343,14 @@ border-radius: 4px; overflow: hidden; margin: 2px; + + &__icons { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 24px; + } } .notification__filter-bar, -- cgit From f59973cc85d9e84bd484ca7c75f108ccbb5d17df Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 3 May 2019 04:34:55 +0200 Subject: [Glitch] Make the "mark media as sensitive" button more obvious in web UI Port 05ef3462ba0af7b147a7cfa8de2735e99dc59ac5 to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/components/media_gallery.js | 2 +- .../glitch/features/compose/components/options.js | 41 ---------------- .../features/compose/components/upload_form.js | 3 ++ .../compose/containers/options_container.js | 5 -- .../containers/sensitive_button_container.js | 54 ++++++++++++++++++++++ .../flavours/glitch/features/video/index.js | 2 +- .../glitch/styles/components/composer.scss | 5 ++ 7 files changed, 64 insertions(+), 48 deletions(-) create mode 100644 app/javascript/flavours/glitch/features/compose/containers/sensitive_button_container.js (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/components/media_gallery.js b/app/javascript/flavours/glitch/components/media_gallery.js index ab1cccc60..194800d52 100644 --- a/app/javascript/flavours/glitch/components/media_gallery.js +++ b/app/javascript/flavours/glitch/components/media_gallery.js @@ -345,7 +345,7 @@ export default class MediaGallery extends React.PureComponent { } if (visible) { - spoilerButton = ; + spoilerButton = ; } else { spoilerButton = (
); } diff --git a/app/javascript/flavours/glitch/features/compose/containers/options_container.js b/app/javascript/flavours/glitch/features/compose/containers/options_container.js index e846cfbd5..2ac7ab8d8 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/options_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/options_container.js @@ -2,7 +2,6 @@ import { connect } from 'react-redux'; import Options from '../components/options'; import { changeComposeAdvancedOption, - changeComposeSensitivity, } from 'flavours/glitch/actions/compose'; import { addPoll, removePoll } from 'flavours/glitch/actions/compose'; import { closeModal, openModal } from 'flavours/glitch/actions/modal'; @@ -27,10 +26,6 @@ const mapDispatchToProps = (dispatch) => ({ dispatch(changeComposeAdvancedOption(option, value)); }, - onChangeSensitivity() { - dispatch(changeComposeSensitivity()); - }, - onTogglePoll() { dispatch((_, getState) => { if (getState().getIn(['compose', 'poll'])) { diff --git a/app/javascript/flavours/glitch/features/compose/containers/sensitive_button_container.js b/app/javascript/flavours/glitch/features/compose/containers/sensitive_button_container.js new file mode 100644 index 000000000..8f163979f --- /dev/null +++ b/app/javascript/flavours/glitch/features/compose/containers/sensitive_button_container.js @@ -0,0 +1,54 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { changeComposeSensitivity } from 'flavours/glitch/actions/compose'; +import { injectIntl, defineMessages, FormattedMessage } from 'react-intl'; +import Icon from 'flavours/glitch/components/icon'; + +const messages = defineMessages({ + marked: { id: 'compose_form.sensitive.marked', defaultMessage: 'Media is marked as sensitive' }, + unmarked: { id: 'compose_form.sensitive.unmarked', defaultMessage: 'Media is not marked as sensitive' }, +}); + +const mapStateToProps = state => { + const spoilersAlwaysOn = state.getIn(['local_settings', 'always_show_spoilers_field']); + const spoilerText = state.getIn(['compose', 'spoiler_text']); + return { + active: state.getIn(['compose', 'sensitive']) || (spoilersAlwaysOn && spoilerText && spoilerText.length > 0), + disabled: state.getIn(['compose', 'spoiler']), + }; +}; + +const mapDispatchToProps = dispatch => ({ + + onClick () { + dispatch(changeComposeSensitivity()); + }, + +}); + +class SensitiveButton extends React.PureComponent { + + static propTypes = { + active: PropTypes.bool, + disabled: PropTypes.bool, + onClick: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, + }; + + render () { + const { active, disabled, onClick, intl } = this.props; + + return ( +
+ +
+ ); + } + +} + +export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(SensitiveButton)); diff --git a/app/javascript/flavours/glitch/features/video/index.js b/app/javascript/flavours/glitch/features/video/index.js index 381485802..8291ff3c8 100644 --- a/app/javascript/flavours/glitch/features/video/index.js +++ b/app/javascript/flavours/glitch/features/video/index.js @@ -500,7 +500,7 @@ export default class Video extends React.PureComponent {
- {!onCloseVideo && } + {!onCloseVideo && } {(!fullscreen && onOpenVideo) && } {onCloseVideo && } diff --git a/app/javascript/flavours/glitch/styles/components/composer.scss b/app/javascript/flavours/glitch/styles/components/composer.scss index e5eb6e64f..81c700737 100644 --- a/app/javascript/flavours/glitch/styles/components/composer.scss +++ b/app/javascript/flavours/glitch/styles/components/composer.scss @@ -57,6 +57,11 @@ } } +.compose-form__sensitive-button { + padding: 10px; + padding-top: 0; +} + .composer--reply { margin: 0 0 10px; border-radius: 4px; -- cgit From 9b1ef58c95f6b0dfa6d22572199fa3cf4337b095 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 3 May 2019 20:44:20 +0200 Subject: [Glitch] Change font weight of sensitive button to 500 Port 63b1388fefff9414c2d0f9883f2d33f7c73284c6 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/styles/components/composer.scss | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/styles/components/composer.scss b/app/javascript/flavours/glitch/styles/components/composer.scss index 81c700737..86041da20 100644 --- a/app/javascript/flavours/glitch/styles/components/composer.scss +++ b/app/javascript/flavours/glitch/styles/components/composer.scss @@ -60,6 +60,11 @@ .compose-form__sensitive-button { padding: 10px; padding-top: 0; + + .icon-button { + font-size: 14px; + font-weight: 500; + } } .composer--reply { -- cgit From f2cf8144b427ba0639cea7976718b0ed77fbf183 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sat, 4 May 2019 23:05:43 +0200 Subject: Minor style fixes --- app/javascript/flavours/glitch/styles/components/sensitive.scss | 1 + 1 file changed, 1 insertion(+) (limited to 'app/javascript/flavours/glitch/styles/components') diff --git a/app/javascript/flavours/glitch/styles/components/sensitive.scss b/app/javascript/flavours/glitch/styles/components/sensitive.scss index 44b7ec981..67b01c886 100644 --- a/app/javascript/flavours/glitch/styles/components/sensitive.scss +++ b/app/javascript/flavours/glitch/styles/components/sensitive.scss @@ -9,6 +9,7 @@ } .sensitive-marker { + margin: 0 3px; border-radius: 2px; padding: 2px 6px; color: rgba($primary-text-color, 0.8); -- cgit