diff options
Diffstat (limited to 'app/javascript/flavours')
20 files changed, 435 insertions, 37 deletions
diff --git a/app/javascript/flavours/glitch/actions/account_notes.js b/app/javascript/flavours/glitch/actions/account_notes.js new file mode 100644 index 000000000..c1cce3193 --- /dev/null +++ b/app/javascript/flavours/glitch/actions/account_notes.js @@ -0,0 +1,69 @@ +import api from 'flavours/glitch/util/api'; + +export const ACCOUNT_NOTE_SUBMIT_REQUEST = 'ACCOUNT_NOTE_SUBMIT_REQUEST'; +export const ACCOUNT_NOTE_SUBMIT_SUCCESS = 'ACCOUNT_NOTE_SUBMIT_SUCCESS'; +export const ACCOUNT_NOTE_SUBMIT_FAIL = 'ACCOUNT_NOTE_SUBMIT_FAIL'; + +export const ACCOUNT_NOTE_INIT_EDIT = 'ACCOUNT_NOTE_INIT_EDIT'; +export const ACCOUNT_NOTE_CANCEL = 'ACCOUNT_NOTE_CANCEL'; + +export const ACCOUNT_NOTE_CHANGE_COMMENT = 'ACCOUNT_NOTE_CHANGE_COMMENT'; + +export function submitAccountNote() { + return (dispatch, getState) => { + dispatch(submitAccountNoteRequest()); + + const id = getState().getIn(['account_notes', 'edit', 'account_id']); + + api(getState).post(`/api/v1/accounts/${id}/note`, { + comment: getState().getIn(['account_notes', 'edit', 'comment']), + }).then(response => { + dispatch(submitAccountNoteSuccess(response.data)); + }).catch(error => dispatch(submitAccountNoteFail(error))); + }; +}; + +export function submitAccountNoteRequest() { + return { + type: ACCOUNT_NOTE_SUBMIT_REQUEST, + }; +}; + +export function submitAccountNoteSuccess(relationship) { + return { + type: ACCOUNT_NOTE_SUBMIT_SUCCESS, + relationship, + }; +}; + +export function submitAccountNoteFail(error) { + return { + type: ACCOUNT_NOTE_SUBMIT_FAIL, + error, + }; +}; + +export function initEditAccountNote(account) { + return (dispatch, getState) => { + const comment = getState().getIn(['relationships', account.get('id'), 'note']); + + dispatch({ + type: ACCOUNT_NOTE_INIT_EDIT, + account, + comment, + }); + }; +}; + +export function cancelAccountNote() { + return { + type: ACCOUNT_NOTE_CANCEL, + }; +}; + +export function changeAccountNoteComment(comment) { + return { + type: ACCOUNT_NOTE_CHANGE_COMMENT, + comment, + }; +}; diff --git a/app/javascript/flavours/glitch/features/account/components/account_note.js b/app/javascript/flavours/glitch/features/account/components/account_note.js new file mode 100644 index 000000000..e7fd4c5ff --- /dev/null +++ b/app/javascript/flavours/glitch/features/account/components/account_note.js @@ -0,0 +1,103 @@ +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import PropTypes from 'prop-types'; +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import Icon from 'flavours/glitch/components/icon'; +import Textarea from 'react-textarea-autosize'; + +const messages = defineMessages({ + placeholder: { id: 'account_note.placeholder', defaultMessage: 'No comment provided' }, +}); + +export default @injectIntl +class Header extends ImmutablePureComponent { + + static propTypes = { + account: ImmutablePropTypes.map.isRequired, + isEditing: PropTypes.bool, + isSubmitting: PropTypes.bool, + accountNote: PropTypes.string, + onEditAccountNote: PropTypes.func.isRequired, + onCancelAccountNote: PropTypes.func.isRequired, + onSaveAccountNote: PropTypes.func.isRequired, + onChangeAccountNote: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, + }; + + handleChangeAccountNote = (e) => { + this.props.onChangeAccountNote(e.target.value); + }; + + componentWillUnmount () { + if (this.props.isEditing) { + this.props.onCancelAccountNote(); + } + } + + handleKeyDown = e => { + if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) { + this.props.onSaveAccountNote(); + } else if (e.keyCode === 27) { + this.props.onCancelAccountNote(); + } + } + + render () { + const { account, accountNote, isEditing, isSubmitting, intl } = this.props; + + if (!account || (!accountNote && !isEditing)) { + return null; + } + + let action_buttons = null; + if (isEditing) { + action_buttons = ( + <div className='account__header__account-note__buttons'> + <button className='text-btn' tabIndex='0' onClick={this.props.onCancelAccountNote} disabled={isSubmitting}> + <Icon id='times' size={15} /> <FormattedMessage id='account_note.cancel' defaultMessage='Cancel' /> + </button> + <div className='flex-spacer' /> + <button className='text-btn' tabIndex='0' onClick={this.props.onSaveAccountNote} disabled={isSubmitting}> + <Icon id='check' size={15} /> <FormattedMessage id='account_note.save' defaultMessage='Save' /> + </button> + </div> + ); + } + + let note_container = null; + if (isEditing) { + note_container = ( + <Textarea + className='account__header__account-note__content' + disabled={isSubmitting} + placeholder={intl.formatMessage(messages.placeholder)} + value={accountNote} + onChange={this.handleChangeAccountNote} + onKeyDown={this.handleKeyDown} + autoFocus + /> + ); + } else { + note_container = (<div className='account__header__account-note__content'>{accountNote}</div>); + } + + return ( + <div className='account__header__account-note'> + <div className='account__header__account-note__header'> + <strong><FormattedMessage id='account.account_note_header' defaultMessage='Your note for @{name}' values={{ name: account.get('username') }} /></strong> + {!isEditing && ( + <div> + <button className='text-btn' tabIndex='0' onClick={this.props.onEditAccountNote} disabled={isSubmitting}> + <Icon id='pencil' size={15} /> <FormattedMessage id='account_note.edit' defaultMessage='Edit' /> + </button> + </div> + )} + </div> + {note_container} + {action_buttons} + </div> + ); + } + +} diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index c7b54649c..a5abf38ae 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -12,6 +12,7 @@ import Button from 'flavours/glitch/components/button'; import { shortNumberFormat } from 'flavours/glitch/util/numbers'; import { NavLink } from 'react-router-dom'; import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container'; +import AccountNoteContainer from '../containers/account_note_container'; const messages = defineMessages({ unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, @@ -46,6 +47,7 @@ const messages = defineMessages({ unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' }, add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' }, admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' }, + add_account_note: { id: 'account.add_account_note', defaultMessage: 'Add note for @{name}' }, }); const dateFormatOptions = { @@ -65,6 +67,7 @@ class Header extends ImmutablePureComponent { identity_props: ImmutablePropTypes.list, onFollow: PropTypes.func.isRequired, onBlock: PropTypes.func.isRequired, + onEditAccountNote: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, domain: PropTypes.string.isRequired, }; @@ -121,6 +124,8 @@ class Header extends ImmutablePureComponent { return null; } + const accountNote = account.getIn(['relationship', 'note']); + let info = []; let actionBtn = ''; let lockedIcon = ''; @@ -172,6 +177,10 @@ class Header extends ImmutablePureComponent { menu.push(null); } + if (accountNote === null) { + menu.push({ text: intl.formatMessage(messages.add_account_note, { name: account.get('username') }), action: this.props.onEditAccountNote }); + } + if (account.get('id') === me) { if (profileLink) menu.push({ text: intl.formatMessage(messages.edit_profile), href: profileLink }); if (preferencesLink) menu.push({ text: intl.formatMessage(messages.preferences), href: preferencesLink }); @@ -278,6 +287,8 @@ class Header extends ImmutablePureComponent { </h1> </div> + <AccountNoteContainer account={account} /> + <div className='account__header__extra'> <div className='account__header__bio'> { (fields.size > 0 || identity_proofs.size > 0) && ( diff --git a/app/javascript/flavours/glitch/features/account/containers/account_note_container.js b/app/javascript/flavours/glitch/features/account/containers/account_note_container.js new file mode 100644 index 000000000..f1d007ecb --- /dev/null +++ b/app/javascript/flavours/glitch/features/account/containers/account_note_container.js @@ -0,0 +1,34 @@ +import { connect } from 'react-redux'; +import { changeAccountNoteComment, submitAccountNote, initEditAccountNote, cancelAccountNote } from 'flavours/glitch/actions/account_notes'; +import AccountNote from '../components/account_note'; + +const mapStateToProps = (state, { account }) => { + const isEditing = state.getIn(['account_notes', 'edit', 'account_id']) === account.get('id'); + + return { + isSubmitting: state.getIn(['account_notes', 'edit', 'isSubmitting']), + accountNote: isEditing ? state.getIn(['account_notes', 'edit', 'comment']) : account.getIn(['relationship', 'note']), + isEditing, + }; +}; + +const mapDispatchToProps = (dispatch, { account }) => ({ + + onEditAccountNote() { + dispatch(initEditAccountNote(account)); + }, + + onSaveAccountNote() { + dispatch(submitAccountNote()); + }, + + onCancelAccountNote() { + dispatch(cancelAccountNote()); + }, + + onChangeAccountNote(comment) { + dispatch(changeAccountNoteComment(comment)); + }, +}); + +export default connect(mapStateToProps, mapDispatchToProps)(AccountNote); diff --git a/app/javascript/flavours/glitch/features/account_timeline/components/header.js b/app/javascript/flavours/glitch/features/account_timeline/components/header.js index 0faa8a424..1bab05c72 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/components/header.js +++ b/app/javascript/flavours/glitch/features/account_timeline/components/header.js @@ -24,6 +24,7 @@ export default class Header extends ImmutablePureComponent { onUnblockDomain: PropTypes.func.isRequired, onEndorseToggle: PropTypes.func.isRequired, onAddToList: PropTypes.func.isRequired, + onEditAccountNote: PropTypes.func.isRequired, hideTabs: PropTypes.bool, domain: PropTypes.string.isRequired, }; @@ -84,6 +85,10 @@ export default class Header extends ImmutablePureComponent { this.props.onAddToList(this.props.account); } + handleEditAccountNote = () => { + this.props.onEditAccountNote(this.props.account); + } + render () { const { account, hideTabs, identity_proofs } = this.props; @@ -109,6 +114,7 @@ export default class Header extends ImmutablePureComponent { onUnblockDomain={this.handleUnblockDomain} onEndorseToggle={this.handleEndorseToggle} onAddToList={this.handleAddToList} + onEditAccountNote={this.handleEditAccountNote} domain={this.props.domain} /> diff --git a/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js b/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js index fff5e097f..225910292 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js +++ b/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js @@ -19,6 +19,7 @@ import { initBlockModal } from 'flavours/glitch/actions/blocks'; import { initReport } from 'flavours/glitch/actions/reports'; import { openModal } from 'flavours/glitch/actions/modal'; import { blockDomain, unblockDomain } from 'flavours/glitch/actions/domain_blocks'; +import { initEditAccountNote } from 'flavours/glitch/actions/account_notes'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { unfollowModal } from 'flavours/glitch/util/initial_state'; import { List as ImmutableList } from 'immutable'; @@ -106,6 +107,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ } }, + onEditAccountNote (account) { + dispatch(initEditAccountNote(account)); + }, + onBlockDomain (domain) { dispatch(openModal('CONFIRM', { message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.' values={{ domain: <strong>{domain}</strong> }} />, diff --git a/app/javascript/flavours/glitch/features/emoji_picker/index.js b/app/javascript/flavours/glitch/features/emoji_picker/index.js index 14e5cb94a..d0d9714a8 100644 --- a/app/javascript/flavours/glitch/features/emoji_picker/index.js +++ b/app/javascript/flavours/glitch/features/emoji_picker/index.js @@ -283,7 +283,7 @@ class EmojiPickerMenu extends React.PureComponent { if (!emoji.native) { emoji.native = emoji.colons; } - if (!event.ctrlKey) { + if (!(event.ctrlKey || event.metaKey)) { this.props.onClose(); } this.props.onPick(emoji); diff --git a/app/javascript/flavours/glitch/features/status/components/card.js b/app/javascript/flavours/glitch/features/status/components/card.js index 03867e03a..d2de225c0 100644 --- a/app/javascript/flavours/glitch/features/status/components/card.js +++ b/app/javascript/flavours/glitch/features/status/components/card.js @@ -7,7 +7,6 @@ import punycode from 'punycode'; import classnames from 'classnames'; import { decode as decodeIDNA } from 'flavours/glitch/util/idna'; import Icon from 'flavours/glitch/components/icon'; -import classNames from 'classnames'; import { useBlurhash } from 'flavours/glitch/util/initial_state'; import { decode } from 'blurhash'; @@ -156,7 +155,9 @@ export default class Card extends React.PureComponent { this.setState({ previewLoaded: true }); } - handleReveal = () => { + handleReveal = e => { + e.preventDefault(); + e.stopPropagation(); this.setState({ revealed: true }); } @@ -194,7 +195,7 @@ export default class Card extends React.PureComponent { const height = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio); const description = ( - <div className={classNames('status-card__content', { 'status-card__content--blurred': !revealed })}> + <div className='status-card__content'> {title} {!(horizontal || compact) && <p className='status-card__description'>{trim(card.get('description') || '', maxDescription)}</p>} <span className='status-card__host'>{provider}</span> @@ -202,7 +203,7 @@ export default class Card extends React.PureComponent { ); let embed = ''; - let canvas = <canvas width={32} height={32} ref={this.setCanvasRef} className={classNames('status-card__image-preview', { 'status-card__image-preview--hidden' : revealed && this.state.previewLoaded })} />; + let canvas = <canvas width={32} height={32} ref={this.setCanvasRef} className={classnames('status-card__image-preview', { 'status-card__image-preview--hidden' : revealed && this.state.previewLoaded })} />; let thumbnail = <img src={card.get('image')} alt='' style={{ width: horizontal ? width : null, height: horizontal ? height : null, visibility: revealed ? null : 'hidden' }} onLoad={this.handleImageLoad} className='status-card__image-image' />; let spoilerButton = ( <button type='button' onClick={this.handleReveal} className='spoiler-button__overlay'> @@ -210,7 +211,7 @@ export default class Card extends React.PureComponent { </button> ); spoilerButton = ( - <div className={classNames('spoiler-button', { 'spoiler-button--minified': revealed })}> + <div className={classnames('spoiler-button', { 'spoiler-button--minified': revealed })}> {spoilerButton} </div> ); @@ -244,7 +245,7 @@ export default class Card extends React.PureComponent { } return ( - <div className={className} ref={this.setRef}> + <div className={className} ref={this.setRef} onClick={revealed ? null : this.handleReveal} role={revealed ? 'button' : null}> {embed} {!compact && description} </div> @@ -254,14 +255,12 @@ export default class Card extends React.PureComponent { <div className='status-card__image'> {canvas} {thumbnail} - {!revealed && spoilerButton} </div> ); } else { embed = ( <div className='status-card__image'> <Icon id='file-text' /> - {!revealed && spoilerButton} </div> ); } diff --git a/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js b/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js index c01d0e5bc..bd2d2eb4e 100644 --- a/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js +++ b/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js @@ -33,6 +33,8 @@ const makeGetStatusIds = (pending = false) => createSelector([ const statusForId = statuses.get(id); let showStatus = true; + if (statusForId.get('account') === me) return true; + if (columnSettings.getIn(['shows', 'reblog']) === false) { showStatus = showStatus && statusForId.get('reblog') === null; } @@ -45,7 +47,7 @@ const makeGetStatusIds = (pending = false) => createSelector([ showStatus = showStatus && statusForId.get('visibility') !== 'direct'; } - if (showStatus && regex && statusForId.get('account') !== me) { + if (showStatus && regex) { const searchIndex = statusForId.get('reblog') ? statuses.getIn([statusForId.get('reblog'), 'search_index']) : statusForId.get('search_index'); showStatus = !regex.test(searchIndex); } diff --git a/app/javascript/flavours/glitch/features/video/index.js b/app/javascript/flavours/glitch/features/video/index.js index a89d9c8b0..e5b681064 100644 --- a/app/javascript/flavours/glitch/features/video/index.js +++ b/app/javascript/flavours/glitch/features/video/index.js @@ -185,15 +185,26 @@ class Video extends React.PureComponent { handlePlay = () => { this.setState({ paused: false }); + this._updateTime(); } handlePause = () => { this.setState({ paused: true }); } + _updateTime () { + requestAnimationFrame(() => { + this.handleTimeUpdate(); + + if (!this.state.paused) { + this._updateTime(); + } + }); + } + handleTimeUpdate = () => { this.setState({ - currentTime: Math.floor(this.video.currentTime), + currentTime: this.video.currentTime, duration: Math.floor(this.video.duration), }); } @@ -231,7 +242,7 @@ class Video extends React.PureComponent { this.video.volume = slideamt; this.setState({ volume: slideamt }); } - }, 60); + }, 15); handleMouseDown = e => { document.addEventListener('mousemove', this.handleMouseMove, true); @@ -259,13 +270,14 @@ class Video extends React.PureComponent { handleMouseMove = throttle(e => { const { x } = getPointerPosition(this.seek, e); - const currentTime = Math.floor(this.video.duration * x); + const currentTime = this.video.duration * x; if (!isNaN(currentTime)) { - this.video.currentTime = currentTime; - this.setState({ currentTime }); + this.setState({ currentTime }, () => { + this.video.currentTime = currentTime; + }); } - }, 60); + }, 15); togglePlay = () => { if (this.state.paused) { @@ -374,8 +386,10 @@ class Video extends React.PureComponent { } handleProgress = () => { - if (this.video.buffered.length > 0) { - this.setState({ buffer: this.video.buffered.end(0) / this.video.duration * 100 }); + const lastTimeRange = this.video.buffered.length - 1; + + if (lastTimeRange > -1) { + this.setState({ buffer: Math.ceil(this.video.buffered.end(lastTimeRange) / this.video.duration * 100) }); } } @@ -477,7 +491,6 @@ class Video extends React.PureComponent { onClick={this.togglePlay} onPlay={this.handlePlay} onPause={this.handlePause} - onTimeUpdate={this.handleTimeUpdate} onLoadedData={this.handleLoadedData} onProgress={this.handleProgress} onVolumeChange={this.handleVolumeChange} @@ -518,7 +531,7 @@ class Video extends React.PureComponent { {(detailed || fullscreen) && ( <span> - <span className='video-player__time-current'>{formatTime(currentTime)}</span> + <span className='video-player__time-current'>{formatTime(Math.floor(currentTime))}</span> <span className='video-player__time-sep'>/</span> <span className='video-player__time-total'>{formatTime(duration)}</span> </span> diff --git a/app/javascript/flavours/glitch/reducers/account_notes.js b/app/javascript/flavours/glitch/reducers/account_notes.js new file mode 100644 index 000000000..b1cf2e0aa --- /dev/null +++ b/app/javascript/flavours/glitch/reducers/account_notes.js @@ -0,0 +1,44 @@ +import { Map as ImmutableMap } from 'immutable'; + +import { + ACCOUNT_NOTE_INIT_EDIT, + ACCOUNT_NOTE_CANCEL, + ACCOUNT_NOTE_CHANGE_COMMENT, + ACCOUNT_NOTE_SUBMIT_REQUEST, + ACCOUNT_NOTE_SUBMIT_FAIL, + ACCOUNT_NOTE_SUBMIT_SUCCESS, +} from '../actions/account_notes'; + +const initialState = ImmutableMap({ + edit: ImmutableMap({ + isSubmitting: false, + account_id: null, + comment: null, + }), +}); + +export default function account_notes(state = initialState, action) { + switch (action.type) { + case ACCOUNT_NOTE_INIT_EDIT: + return state.withMutations((state) => { + state.setIn(['edit', 'isSubmitting'], false); + state.setIn(['edit', 'account_id'], action.account.get('id')); + state.setIn(['edit', 'comment'], action.comment); + }); + case ACCOUNT_NOTE_CHANGE_COMMENT: + return state.setIn(['edit', 'comment'], action.comment); + case ACCOUNT_NOTE_SUBMIT_REQUEST: + return state.setIn(['edit', 'isSubmitting'], true); + case ACCOUNT_NOTE_SUBMIT_FAIL: + return state.setIn(['edit', 'isSubmitting'], false); + case ACCOUNT_NOTE_SUBMIT_SUCCESS: + case ACCOUNT_NOTE_CANCEL: + return state.withMutations((state) => { + state.setIn(['edit', 'isSubmitting'], false); + state.setIn(['edit', 'account_id'], null); + state.setIn(['edit', 'comment'], null); + }); + default: + return state; + } +} diff --git a/app/javascript/flavours/glitch/reducers/index.js b/app/javascript/flavours/glitch/reducers/index.js index 852abe9dd..cadbd01a3 100644 --- a/app/javascript/flavours/glitch/reducers/index.js +++ b/app/javascript/flavours/glitch/reducers/index.js @@ -37,6 +37,7 @@ import identity_proofs from './identity_proofs'; import trends from './trends'; import announcements from './announcements'; import markers from './markers'; +import account_notes from './account_notes'; const reducers = { announcements, @@ -77,6 +78,7 @@ const reducers = { polls, trends, markers, + account_notes, }; export default combineReducers(reducers); diff --git a/app/javascript/flavours/glitch/reducers/markers.js b/app/javascript/flavours/glitch/reducers/markers.js index 2e67be82e..fb1572ff5 100644 --- a/app/javascript/flavours/glitch/reducers/markers.js +++ b/app/javascript/flavours/glitch/reducers/markers.js @@ -1,6 +1,6 @@ import { MARKERS_SUBMIT_SUCCESS, -} from '../actions/notifications'; +} from '../actions/markers'; const initialState = ImmutableMap({ home: '0', diff --git a/app/javascript/flavours/glitch/reducers/relationships.js b/app/javascript/flavours/glitch/reducers/relationships.js index 4652bbc14..dcaeefcae 100644 --- a/app/javascript/flavours/glitch/reducers/relationships.js +++ b/app/javascript/flavours/glitch/reducers/relationships.js @@ -13,6 +13,9 @@ import { DOMAIN_BLOCK_SUCCESS, DOMAIN_UNBLOCK_SUCCESS, } from 'flavours/glitch/actions/domain_blocks'; +import { + ACCOUNT_NOTE_SUBMIT_SUCCESS, +} from 'flavours/glitch/actions/account_notes'; import { Map as ImmutableMap, fromJS } from 'immutable'; const normalizeRelationship = (state, relationship) => state.set(relationship.id, fromJS(relationship)); @@ -45,6 +48,7 @@ export default function relationships(state = initialState, action) { case ACCOUNT_UNMUTE_SUCCESS: case ACCOUNT_PIN_SUCCESS: case ACCOUNT_UNPIN_SUCCESS: + case ACCOUNT_NOTE_SUBMIT_SUCCESS: return normalizeRelationship(state, action.relationship); case RELATIONSHIPS_FETCH_SUCCESS: return normalizeRelationships(state, action.relationships); diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index 1c8f2271f..3cf5ee970 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -171,9 +171,7 @@ $content-width: 840px; } .content { - padding: 20px 15px; - padding-top: 60px; - padding-left: 25px; + padding: 55px 15px 20px 25px; @media screen and (max-width: $no-columns-breakpoint) { max-width: none; @@ -184,7 +182,7 @@ $content-width: 840px; &-heading { display: flex; - padding-bottom: 40px; + padding-bottom: 36px; border-bottom: 1px solid lighten($ui-base-color, 8%); margin: -15px -15px 40px 0; @@ -215,7 +213,7 @@ $content-width: 840px; h2 { color: $secondary-text-color; font-size: 24px; - line-height: 28px; + line-height: 36px; font-weight: 400; @media screen and (max-width: $no-columns-breakpoint) { @@ -528,6 +526,16 @@ body, max-width: 100%; } +.simple_form { + .actions { + margin-top: 15px; + } + + .button { + font-size: 15px; + } +} + .batch-form-box { display: flex; flex-wrap: wrap; diff --git a/app/javascript/flavours/glitch/styles/basics.scss b/app/javascript/flavours/glitch/styles/basics.scss index 9ff3f3bac..be0e1b860 100644 --- a/app/javascript/flavours/glitch/styles/basics.scss +++ b/app/javascript/flavours/glitch/styles/basics.scss @@ -66,6 +66,35 @@ body { } } + &.player { + padding: 0; + margin: 0; + position: absolute; + width: 100%; + height: 100%; + overflow: hidden; + + & > div { + height: 100%; + } + + .video-player video { + width: 100%; + height: 100%; + max-height: 100vh; + } + + .media-gallery { + margin-top: 0; + height: 100% !important; + border-radius: 0; + } + + .media-gallery__item { + border-radius: 0; + } + } + &.embed { background: lighten($ui-base-color, 4%); margin: 0; diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss index 610e48f92..774254a4c 100644 --- a/app/javascript/flavours/glitch/styles/components/accounts.scss +++ b/app/javascript/flavours/glitch/styles/components/accounts.scss @@ -379,7 +379,6 @@ color: $primary-text-color; margin-bottom: 4px; display: block; - vertical-align: top; background-color: $base-overlay-background; text-transform: uppercase; font-size: 11px; @@ -605,7 +604,7 @@ &__tabs { display: flex; align-items: flex-start; - padding: 7px 5px; + padding: 7px 10px; margin-top: -55px; &__buttons { @@ -627,7 +626,7 @@ } &__name { - padding: 5px; + padding: 5px 10px; .account-role { vertical-align: top; @@ -713,4 +712,65 @@ } } } + + &__account-note { + margin: 5px; + padding: 10px; + background: $ui-highlight-color; + color: $primary-text-color; + display: flex; + flex-direction: column; + border-radius: 4px; + font-size: 14px; + font-weight: 400; + + &__header { + display: flex; + flex-direction: row; + justify-content: space-between; + } + + &__content { + white-space: pre-wrap; + margin-top: 5px; + } + + &__buttons { + display: flex; + flex-direction: row; + justify-content: flex-end; + margin-top: 5px; + + .flex-spacer { + flex: 0 0 20px; + background: transparent; + } + } + + strong { + font-size: 15px; + font-weight: 500; + } + + button:hover span { + text-decoration: underline; + } + + textarea { + display: block; + box-sizing: border-box; + width: 100%; + margin: 0; + margin-top: 5px; + color: $inverted-text-color; + background: $simple-background-color; + padding: 10px; + font-family: inherit; + font-size: 14px; + resize: none; + border: 0; + outline: 0; + border-radius: 4px; + } + } } diff --git a/app/javascript/flavours/glitch/styles/components/media.scss b/app/javascript/flavours/glitch/styles/components/media.scss index dbf0c908d..772b40dc4 100644 --- a/app/javascript/flavours/glitch/styles/components/media.scss +++ b/app/javascript/flavours/glitch/styles/components/media.scss @@ -76,7 +76,7 @@ border-radius: 4px; position: relative; width: 100%; - height: 110px; + min-height: 64px; @include fullwidth-gallery; } @@ -404,6 +404,7 @@ @include fullwidth-gallery; video { + display: block; max-width: 100vw; max-height: 80vh; z-index: 1; diff --git a/app/javascript/flavours/glitch/styles/components/status.scss b/app/javascript/flavours/glitch/styles/components/status.scss index 28a4ce0ce..fe4f16353 100644 --- a/app/javascript/flavours/glitch/styles/components/status.scss +++ b/app/javascript/flavours/glitch/styles/components/status.scss @@ -776,6 +776,7 @@ a.status__display-name, } .status-card { + position: relative; display: flex; font-size: 14px; border: 1px solid lighten($ui-base-color, 8%); @@ -874,11 +875,6 @@ a.status-card { flex: 1 1 auto; overflow: hidden; padding: 14px 14px 14px 8px; - - &--blurred { - filter: blur(2px); - pointer-events: none; - } } .status-card__description { diff --git a/app/javascript/flavours/glitch/styles/statuses.scss b/app/javascript/flavours/glitch/styles/statuses.scss index 6fcc11e29..a71bb2552 100644 --- a/app/javascript/flavours/glitch/styles/statuses.scss +++ b/app/javascript/flavours/glitch/styles/statuses.scss @@ -136,6 +136,11 @@ .detailed-status { padding: 15px; + + .detailed-status__display-avatar .account__avatar { + width: 48px; + height: 48px; + } } .status { @@ -196,7 +201,8 @@ display: initial; } - .status__relative-time { + .status__relative-time, + .status__visibility-icon { color: $dark-text-color; float: right; font-size: 14px; @@ -205,6 +211,11 @@ padding: initial; } + .status__visibility-icon { + margin-left: 4px; + margin-right: 4px; + } + .status__info .status__display-name { display: block; max-width: 100%; @@ -238,7 +249,8 @@ padding-right: 0; } - .status__relative-time { + .status__relative-time, + .status__visibility-icon { float: left; } } |