mirror of
https://git.kescher.at/CatCatNya/catstodon.git
synced 2024-11-26 07:51:37 +01:00
Merge remote-tracking branch 'upstream/main' into develop
This commit is contained in:
commit
628c027049
40 changed files with 88 additions and 200 deletions
|
@ -1,10 +1,8 @@
|
|||
// This file will be loaded on public pages, regardless of theme.
|
||||
|
||||
import 'packs/public-path';
|
||||
import ready from '../mastodon/ready';
|
||||
|
||||
const { delegate } = require('@rails/ujs');
|
||||
const { length } = require('stringz');
|
||||
|
||||
const getProfileAvatarAnimationHandler = (swapTo) => {
|
||||
//animate avatar gifs on the profile page when moused over
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import api, { getLinks } from '../api';
|
||||
import { importAccount, importFetchedAccount, importFetchedAccounts } from './importer';
|
||||
import { importFetchedAccount, importFetchedAccounts } from './importer';
|
||||
|
||||
export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST';
|
||||
export const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS';
|
||||
|
|
|
@ -3,7 +3,7 @@ import { submitMarkers } from './markers';
|
|||
import api, { getLinks } from 'flavours/glitch/api';
|
||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||
import compareId from 'flavours/glitch/compare_id';
|
||||
import { me, usePendingItems as preferPendingItems } from 'flavours/glitch/initial_state';
|
||||
import { usePendingItems as preferPendingItems } from 'flavours/glitch/initial_state';
|
||||
import { toServerSideType } from 'flavours/glitch/utils/filters';
|
||||
|
||||
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
|
||||
|
@ -121,7 +121,6 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
|
|||
|
||||
api(getState).get(path, { params }).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||
|
||||
dispatch(importFetchedStatuses(response.data));
|
||||
dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.status === 206, isLoadingRecent, isLoadingMore, isLoadingRecent && preferPendingItems));
|
||||
|
||||
|
@ -163,10 +162,10 @@ export const expandListTimeline = (id, { maxId } = {}, done = noOp) =
|
|||
export const expandHashtagTimeline = (hashtag, { maxId, tags, local } = {}, done = noOp) => {
|
||||
return expandTimeline(`hashtag:${hashtag}${local ? ':local' : ''}`, `/api/v1/timelines/tag/${hashtag}`, {
|
||||
max_id: maxId,
|
||||
any: parseTags(tags, 'any'),
|
||||
all: parseTags(tags, 'all'),
|
||||
none: parseTags(tags, 'none'),
|
||||
local: local,
|
||||
any: parseTags(tags, 'any'),
|
||||
all: parseTags(tags, 'all'),
|
||||
none: parseTags(tags, 'none'),
|
||||
local: local,
|
||||
}, done);
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ export default class AvatarComposite extends React.PureComponent {
|
|||
accounts: ImmutablePropTypes.list.isRequired,
|
||||
animate: PropTypes.bool,
|
||||
size: PropTypes.number.isRequired,
|
||||
onAccountClick: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
|
|
@ -14,6 +14,7 @@ export default class DisplayName extends React.PureComponent {
|
|||
localDomain: PropTypes.string,
|
||||
others: ImmutablePropTypes.list,
|
||||
handleClick: PropTypes.func,
|
||||
onAccountClick: PropTypes.func,
|
||||
};
|
||||
|
||||
handleMouseEnter = ({ currentTarget }) => {
|
||||
|
@ -61,6 +62,7 @@ export default class DisplayName extends React.PureComponent {
|
|||
if (others && others.size > 0) {
|
||||
displayName = others.take(2).map(a => (
|
||||
<a
|
||||
key={a.get('id')}
|
||||
href={a.get('url')}
|
||||
target='_blank'
|
||||
onClick={(e) => onAccountClick(a.get('acct'), e)}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React from 'react';
|
||||
import Motion from '../features/ui/util/optional_motion';
|
||||
import spring from 'react-motion/lib/spring';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import Icon from 'flavours/glitch/components/icon';
|
||||
|
@ -25,7 +23,7 @@ export default class IconButton extends React.PureComponent {
|
|||
inverted: PropTypes.bool,
|
||||
animate: PropTypes.bool,
|
||||
overlay: PropTypes.bool,
|
||||
tabIndex: PropTypes.string,
|
||||
tabIndex: PropTypes.number,
|
||||
label: PropTypes.string,
|
||||
counter: PropTypes.number,
|
||||
obfuscateCount: PropTypes.bool,
|
||||
|
@ -39,7 +37,7 @@ export default class IconButton extends React.PureComponent {
|
|||
disabled: false,
|
||||
animate: false,
|
||||
overlay: false,
|
||||
tabIndex: '0',
|
||||
tabIndex: 0,
|
||||
ariaHidden: false,
|
||||
};
|
||||
|
||||
|
@ -156,6 +154,7 @@ export default class IconButton extends React.PureComponent {
|
|||
|
||||
return (
|
||||
<button
|
||||
type='button'
|
||||
aria-label={title}
|
||||
aria-expanded={expanded}
|
||||
aria-hidden={ariaHidden}
|
||||
|
|
|
@ -289,7 +289,7 @@ class MediaGallery extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
componentDidUpdate () {
|
||||
if (this.node) {
|
||||
this.handleResize();
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ class MediaGallery extends React.PureComponent {
|
|||
_setDimensions () {
|
||||
const width = this.node.offsetWidth;
|
||||
|
||||
if (width && width != this.state.width) {
|
||||
if (width && width !== this.state.width) {
|
||||
// offsetWidth triggers a layout, so only calculate when we need to
|
||||
if (this.props.cacheWidth) {
|
||||
this.props.cacheWidth(width);
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
export default
|
||||
class Spoilers extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
spoilerText: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
state = {
|
||||
hidden: true,
|
||||
};
|
||||
|
||||
handleSpoilerClick = () => {
|
||||
this.setState({ hidden: !this.state.hidden });
|
||||
};
|
||||
|
||||
render () {
|
||||
const { spoilerText, children } = this.props;
|
||||
const { hidden } = this.state;
|
||||
|
||||
const toggleText = hidden ?
|
||||
(<FormattedMessage
|
||||
id='status.show_more'
|
||||
defaultMessage='Show more'
|
||||
key='0'
|
||||
/>) :
|
||||
(<FormattedMessage
|
||||
id='status.show_less'
|
||||
defaultMessage='Show less'
|
||||
key='0'
|
||||
/>);
|
||||
|
||||
return ([
|
||||
<p className='spoiler__text'>
|
||||
{spoilerText}
|
||||
{' '}
|
||||
<button tabIndex={0} className='status__content__spoiler-link' onClick={this.handleSpoilerClick}>
|
||||
{toggleText}
|
||||
</button>
|
||||
</p>,
|
||||
<div className={`status__content__spoiler ${!hidden ? 'status__content__spoiler--visible' : ''}`}>
|
||||
{children}
|
||||
</div>,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -286,7 +286,7 @@ class Status extends ImmutablePureComponent {
|
|||
|
||||
// Hack to fix timeline jumps on second rendering when auto-collapsing
|
||||
// or on subsequent rendering when a preview card has been fetched
|
||||
getSnapshotBeforeUpdate (prevProps, prevState) {
|
||||
getSnapshotBeforeUpdate() {
|
||||
if (!this.props.getScrollPosition) return null;
|
||||
|
||||
const { muted, hidden, status, settings } = this.props;
|
||||
|
@ -301,7 +301,7 @@ class Status extends ImmutablePureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps, prevState, snapshot) {
|
||||
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
if (snapshot !== null && this.props.updateScrollBottom && this.node.offsetTop < snapshot.top) {
|
||||
this.props.updateScrollBottom(snapshot.height - snapshot.top);
|
||||
}
|
||||
|
@ -465,7 +465,7 @@ class Status extends ImmutablePureComponent {
|
|||
this.props.onMoveDown(this.props.containerId || this.props.id, e.target.getAttribute('data-featured'));
|
||||
};
|
||||
|
||||
handleHotkeyCollapse = e => {
|
||||
handleHotkeyCollapse = () => {
|
||||
if (!this.props.settings.getIn(['collapsed', 'enabled']))
|
||||
return;
|
||||
|
||||
|
@ -509,7 +509,6 @@ class Status extends ImmutablePureComponent {
|
|||
const {
|
||||
handleRef,
|
||||
parseClick,
|
||||
setExpansion,
|
||||
setCollapsed,
|
||||
} = this;
|
||||
const { router } = this.context;
|
||||
|
@ -533,7 +532,7 @@ class Status extends ImmutablePureComponent {
|
|||
rootId,
|
||||
...other
|
||||
} = this.props;
|
||||
const { isCollapsed, forceFilter } = this.state;
|
||||
const { isCollapsed } = this.state;
|
||||
let background = null;
|
||||
let attachments = null;
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
|||
// Mastodon imports.
|
||||
import Avatar from './avatar';
|
||||
import AvatarOverlay from './avatar_overlay';
|
||||
import AvatarComposite from './avatar_composite';
|
||||
import DisplayName from './display_name';
|
||||
|
||||
export default class StatusHeader extends React.PureComponent {
|
||||
|
|
|
@ -64,18 +64,15 @@ class StatusIcons extends React.PureComponent {
|
|||
mediaIconTitleText (mediaIcon) {
|
||||
const { intl } = this.props;
|
||||
|
||||
switch (mediaIcon) {
|
||||
case 'link':
|
||||
return intl.formatMessage(messages.previewCard);
|
||||
case 'picture-o':
|
||||
return intl.formatMessage(messages.pictures);
|
||||
case 'tasks':
|
||||
return intl.formatMessage(messages.poll);
|
||||
case 'video-camera':
|
||||
return intl.formatMessage(messages.video);
|
||||
case 'music':
|
||||
return intl.formatMessage(messages.audio);
|
||||
}
|
||||
const message = {
|
||||
'link': messages.previewCard,
|
||||
'picture-o': messages.pictures,
|
||||
'tasks': messages.poll,
|
||||
'video-camera': messages.video,
|
||||
'music': messages.audio,
|
||||
}[mediaIcon];
|
||||
|
||||
return message && intl.formatMessage(message);
|
||||
}
|
||||
|
||||
renderIcon (mediaIcon) {
|
||||
|
|
|
@ -10,8 +10,7 @@ const messages = defineMessages({
|
|||
});
|
||||
|
||||
const makeMapStateToProps = () => {
|
||||
const mapStateToProps = (state, { }) => ({
|
||||
});
|
||||
const mapStateToProps = () => ({});
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { connect } from 'react-redux';
|
||||
import Status from 'flavours/glitch/components/status';
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
import { makeGetStatus, makeGetPictureInPicture } from 'flavours/glitch/selectors';
|
||||
import {
|
||||
replyCompose,
|
||||
|
@ -39,13 +38,9 @@ import { initBoostModal } from 'flavours/glitch/actions/boosts';
|
|||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { deployPictureInPicture } from 'flavours/glitch/actions/picture_in_picture';
|
||||
import { changeLocalSetting } from 'flavours/glitch/actions/local_settings';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { boostModal, favouriteModal, deleteModal } from 'flavours/glitch/initial_state';
|
||||
import { filterEditLink } from 'flavours/glitch/utils/backend_links';
|
||||
import { showAlertForError } from '../actions/alerts';
|
||||
import AccountContainer from 'flavours/glitch/containers/account_container';
|
||||
import Spoilers from '../components/spoilers';
|
||||
import Icon from 'flavours/glitch/components/icon';
|
||||
|
||||
const messages = defineMessages({
|
||||
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import PropTypes from 'prop-types';
|
||||
import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { injectIntl, FormattedMessage, FormattedNumber } from 'react-intl';
|
||||
import { me, isStaff } from 'flavours/glitch/initial_state';
|
||||
import { profileLink, accountAdminLink } from 'flavours/glitch/utils/backend_links';
|
||||
import { FormattedMessage, FormattedNumber } from 'react-intl';
|
||||
import Icon from 'flavours/glitch/components/icon';
|
||||
|
||||
class ActionBar extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
account: ImmutablePropTypes.map.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
isStatusesPageActive = (match, location) => {
|
||||
|
@ -23,7 +18,7 @@ class ActionBar extends React.PureComponent {
|
|||
};
|
||||
|
||||
render () {
|
||||
const { account, intl } = this.props;
|
||||
const { account } = this.props;
|
||||
|
||||
if (account.get('suspended')) {
|
||||
return (
|
||||
|
@ -83,4 +78,4 @@ class ActionBar extends React.PureComponent {
|
|||
|
||||
}
|
||||
|
||||
export default injectIntl(ActionBar);
|
||||
export default ActionBar;
|
||||
|
|
|
@ -14,6 +14,7 @@ import HeaderContainer from 'flavours/glitch/features/account_timeline/container
|
|||
import ScrollContainer from 'flavours/glitch/containers/scroll_container';
|
||||
import LoadMore from 'flavours/glitch/components/load_more';
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { normalizeForLookup } from 'flavours/glitch/reducers/accounts_map';
|
||||
import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error';
|
||||
|
||||
|
@ -71,8 +72,8 @@ class AccountGallery extends ImmutablePureComponent {
|
|||
isLoading: PropTypes.bool,
|
||||
hasMore: PropTypes.bool,
|
||||
isAccount: PropTypes.bool,
|
||||
multiColumn: PropTypes.bool,
|
||||
suspended: PropTypes.bool,
|
||||
multiColumn: PropTypes.bool,
|
||||
};
|
||||
|
||||
state = {
|
||||
|
|
|
@ -93,10 +93,6 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
|||
dispatch(directCompose(account, router));
|
||||
},
|
||||
|
||||
onDirect (account, router) {
|
||||
dispatch(directCompose(account, router));
|
||||
},
|
||||
|
||||
onReblogToggle (account) {
|
||||
if (account.getIn(['relationship', 'showing_reblogs'])) {
|
||||
dispatch(followAccount(account.get('id'), { reblogs: false }));
|
||||
|
|
|
@ -9,7 +9,6 @@ import LoadingIndicator from '../../components/loading_indicator';
|
|||
import Column from '../ui/components/column';
|
||||
import ProfileColumnHeader from 'flavours/glitch/features/account/components/profile_column_header';
|
||||
import HeaderContainer from './containers/header_container';
|
||||
import ColumnBackButton from 'flavours/glitch/components/column_back_button';
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
|
|
@ -94,7 +94,7 @@ class Audio extends React.PureComponent {
|
|||
const width = this.player.offsetWidth;
|
||||
const height = this.props.fullscreen ? this.player.offsetHeight : (width / (16/9));
|
||||
|
||||
if (width && width != this.state.containerWidth) {
|
||||
if (width && width !== this.state.containerWidth) {
|
||||
if (this.props.cacheWidth) {
|
||||
this.props.cacheWidth(width);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React from 'react';
|
||||
import CharacterCounter from './character_counter';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import PropTypes from 'prop-types';
|
||||
import ReplyIndicatorContainer from '../containers/reply_indicator_container';
|
||||
|
@ -11,13 +12,12 @@ import UploadFormContainer from '../containers/upload_form_container';
|
|||
import WarningContainer from '../containers/warning_container';
|
||||
import { isMobile } from 'flavours/glitch/is_mobile';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { length } from 'stringz';
|
||||
import { countableText } from '../util/counter';
|
||||
import { maxChars } from 'flavours/glitch/initial_state';
|
||||
import OptionsContainer from '../containers/options_container';
|
||||
import Publisher from './publisher';
|
||||
import TextareaIcons from './textarea_icons';
|
||||
import { maxChars } from 'flavours/glitch/initial_state';
|
||||
import CharacterCounter from './character_counter';
|
||||
import { length } from 'stringz';
|
||||
|
||||
const messages = defineMessages({
|
||||
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
|
||||
|
@ -76,7 +76,6 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
preselectOnReply: PropTypes.bool,
|
||||
onChangeSpoilerness: PropTypes.func,
|
||||
onChangeVisibility: PropTypes.func,
|
||||
onPaste: PropTypes.func,
|
||||
onMediaDescriptionConfirm: PropTypes.func,
|
||||
};
|
||||
|
||||
|
@ -164,11 +163,11 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
};
|
||||
|
||||
// Selects a suggestion from the autofill.
|
||||
onSuggestionSelected = (tokenStart, token, value) => {
|
||||
handleSuggestionSelected = (tokenStart, token, value) => {
|
||||
this.props.onSuggestionSelected(tokenStart, token, value, ['text']);
|
||||
};
|
||||
|
||||
onSpoilerSuggestionSelected = (tokenStart, token, value) => {
|
||||
handleSpoilerSuggestionSelected = (tokenStart, token, value) => {
|
||||
this.props.onSuggestionSelected(tokenStart, token, value, ['spoiler_text']);
|
||||
};
|
||||
|
||||
|
@ -177,7 +176,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
this.handleSubmit();
|
||||
}
|
||||
|
||||
if (e.keyCode == 13 && e.altKey) {
|
||||
if (e.keyCode === 13 && e.altKey) {
|
||||
this.handleSecondarySubmit();
|
||||
}
|
||||
};
|
||||
|
@ -281,9 +280,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
const {
|
||||
handleEmojiPick,
|
||||
handleSecondarySubmit,
|
||||
handleSelect,
|
||||
handleSubmit,
|
||||
handleRefTextarea,
|
||||
} = this;
|
||||
const {
|
||||
advancedOptions,
|
||||
|
@ -291,7 +288,6 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
isSubmitting,
|
||||
layout,
|
||||
onChangeSpoilerness,
|
||||
onChangeVisibility,
|
||||
onClearSuggestions,
|
||||
onFetchSuggestions,
|
||||
onPaste,
|
||||
|
@ -322,10 +318,10 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
onKeyDown={this.handleKeyDown}
|
||||
disabled={!spoiler}
|
||||
ref={this.handleRefSpoilerText}
|
||||
suggestions={this.props.suggestions}
|
||||
suggestions={suggestions}
|
||||
onSuggestionsFetchRequested={onFetchSuggestions}
|
||||
onSuggestionsClearRequested={onClearSuggestions}
|
||||
onSuggestionSelected={this.onSpoilerSuggestionSelected}
|
||||
onSuggestionSelected={this.handleSpoilerSuggestionSelected}
|
||||
searchTokens={[':']}
|
||||
id='glitch.composer.spoiler.input'
|
||||
className='spoiler-input__input'
|
||||
|
@ -342,11 +338,11 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
value={this.props.text}
|
||||
onChange={this.handleChange}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
suggestions={this.props.suggestions}
|
||||
suggestions={suggestions}
|
||||
onFocus={this.handleFocus}
|
||||
onSuggestionsFetchRequested={onFetchSuggestions}
|
||||
onSuggestionsClearRequested={onClearSuggestions}
|
||||
onSuggestionSelected={this.onSuggestionSelected}
|
||||
onSuggestionSelected={this.handleSuggestionSelected}
|
||||
onPaste={onPaste}
|
||||
autoFocus={!showSearch && !isMobile(window.innerWidth, layout)}
|
||||
lang={this.props.lang}
|
||||
|
|
|
@ -8,9 +8,6 @@ import Overlay from 'react-overlays/Overlay';
|
|||
import IconButton from 'flavours/glitch/components/icon_button';
|
||||
import DropdownMenu from './dropdown_menu';
|
||||
|
||||
// Utils.
|
||||
import { assignHandlers } from 'flavours/glitch/utils/react_helpers';
|
||||
|
||||
// The component.
|
||||
export default class ComposerOptionsDropdown extends React.PureComponent {
|
||||
|
||||
|
@ -50,7 +47,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
|
|||
const { open } = this.state;
|
||||
|
||||
if (this.props.isUserTouching && this.props.isUserTouching()) {
|
||||
if (this.state.open) {
|
||||
if (open) {
|
||||
this.props.onModalClose();
|
||||
} else {
|
||||
const modal = this.handleMakeModal();
|
||||
|
@ -59,10 +56,10 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (this.state.open && this.activeElement) {
|
||||
if (open && this.activeElement) {
|
||||
this.activeElement.focus({ preventScroll: true });
|
||||
}
|
||||
this.setState({ open: !this.state.open, openedViaKeyboard: type !== 'click' });
|
||||
this.setState({ open: !open, openedViaKeyboard: type !== 'click' });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Package imports.
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import classNames from 'classnames';
|
||||
|
||||
// Components.
|
||||
|
@ -9,7 +8,6 @@ import Icon from 'flavours/glitch/components/icon';
|
|||
|
||||
// Utils.
|
||||
import { withPassive } from 'flavours/glitch/utils/dom_helpers';
|
||||
import { assignHandlers } from 'flavours/glitch/utils/react_helpers';
|
||||
|
||||
// The component.
|
||||
export default class ComposerOptionsDropdownContent extends React.PureComponent {
|
||||
|
@ -78,7 +76,8 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
|
|||
items,
|
||||
} = this.props;
|
||||
|
||||
const { name } = this.props.items[i];
|
||||
const { name } = items[i];
|
||||
|
||||
e.preventDefault(); // Prevents change in focus on click
|
||||
if (closeOnChange) {
|
||||
onClose();
|
||||
|
@ -131,7 +130,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
|
|||
|
||||
if (element) {
|
||||
element.focus();
|
||||
this.handleChange(this.props.items[Number(element.getAttribute('data-index'))].name);
|
||||
this.handleChange(items[Number(element.getAttribute('data-index'))].name);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
@ -169,6 +168,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
|
|||
onClick={this.handleClick}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
role='option'
|
||||
aria-selected={active}
|
||||
tabIndex={0}
|
||||
key={name}
|
||||
data-index={i}
|
||||
|
@ -183,8 +183,6 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
|
|||
render () {
|
||||
const {
|
||||
items,
|
||||
onChange,
|
||||
onClose,
|
||||
style,
|
||||
} = this.props;
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ class PollForm extends ImmutablePureComponent {
|
|||
</ul>
|
||||
|
||||
<div className='poll__footer'>
|
||||
{/* eslint-disable-next-line jsx-a11y/no-onchange */}
|
||||
<select value={isMultiple ? 'true' : 'false'} onChange={this.handleSelectMultiple}>
|
||||
<option value='false'>{intl.formatMessage(messages.single_choice)}</option>
|
||||
<option value='true'>{intl.formatMessage(messages.multiple_choices)}</option>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import Dropdown from './dropdown';
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Package imports.
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
injectIntl,
|
||||
FormattedMessage,
|
||||
|
|
|
@ -6,7 +6,6 @@ import spring from 'react-motion/lib/spring';
|
|||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import Icon from 'flavours/glitch/components/icon';
|
||||
import { isUserTouching } from 'flavours/glitch/is_mobile';
|
||||
|
||||
export default class Upload extends ImmutablePureComponent {
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import React from 'react';
|
|||
import ComposeFormContainer from './containers/compose_form_container';
|
||||
import NavigationContainer from './containers/navigation_container';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { connect } from 'react-redux';
|
||||
import { mountCompose, unmountCompose, cycleElefriendCompose } from 'flavours/glitch/actions/compose';
|
||||
import { injectIntl, defineMessages } from 'react-intl';
|
||||
|
@ -11,7 +10,7 @@ import SearchContainer from './containers/search_container';
|
|||
import Motion from '../ui/util/optional_motion';
|
||||
import spring from 'react-motion/lib/spring';
|
||||
import SearchResultsContainer from './containers/search_results_container';
|
||||
import { me, mascot } from 'flavours/glitch/initial_state';
|
||||
import { mascot } from 'flavours/glitch/initial_state';
|
||||
import HeaderContainer from './containers/header_container';
|
||||
import Column from 'flavours/glitch/components/column';
|
||||
import { Helmet } from 'react-helmet';
|
||||
|
@ -25,7 +24,7 @@ const mapStateToProps = (state, ownProps) => ({
|
|||
showSearch: ownProps.multiColumn ? state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']) : false,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onClickElefriend () {
|
||||
dispatch(cycleElefriendCompose());
|
||||
},
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import Column from 'flavours/glitch/features/ui/components/column';
|
||||
import ColumnLink from 'flavours/glitch/features/ui/components/column_link';
|
||||
import ColumnSubheading from 'flavours/glitch/features/ui/components/column_subheading';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import PropTypes from 'prop-types';
|
||||
|
@ -76,8 +76,6 @@ const badgeDisplay = (number, limit) => {
|
|||
}
|
||||
};
|
||||
|
||||
const NAVIGATION_PANEL_BREAKPOINT = 600 + (285 * 2) + (10 * 2);
|
||||
|
||||
class GettingStarted extends ImmutablePureComponent {
|
||||
|
||||
static contextTypes = {
|
||||
|
@ -188,7 +186,7 @@ class GettingStarted extends ImmutablePureComponent {
|
|||
<LinkFooter />
|
||||
</div>
|
||||
|
||||
{multiColumn && showTrends && <TrendsContainer />}
|
||||
{(multiColumn && showTrends) && <TrendsContainer />}
|
||||
|
||||
<Helmet>
|
||||
<title>{intl.formatMessage(messages.menu)}</title>
|
||||
|
|
|
@ -34,11 +34,11 @@ class GettingStartedMisc extends ImmutablePureComponent {
|
|||
dispatch: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
openOnboardingModal = (e) => {
|
||||
openOnboardingModal = () => {
|
||||
this.props.dispatch(openModal('ONBOARDING'));
|
||||
};
|
||||
|
||||
openFeaturedAccountsModal = (e) => {
|
||||
openFeaturedAccountsModal = () => {
|
||||
this.props.dispatch(openModal('PINNED_ACCOUNTS_EDITOR'));
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { makeGetAccount } from 'flavours/glitch/selectors';
|
||||
import { injectIntl } from 'react-intl';
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import { fetchListSuggestions, clearListSuggestions, changeListSuggestions } from '../../../actions/lists';
|
||||
|
|
|
@ -133,9 +133,9 @@ class ListTimeline extends React.PureComponent {
|
|||
};
|
||||
|
||||
handleRepliesPolicyChange = ({ target }) => {
|
||||
const { dispatch, list } = this.props;
|
||||
const { dispatch } = this.props;
|
||||
const { id } = this.props.params;
|
||||
this.props.dispatch(updateList(id, undefined, false, target.value));
|
||||
dispatch(updateList(id, undefined, false, target.value));
|
||||
};
|
||||
|
||||
render () {
|
||||
|
@ -172,11 +172,11 @@ class ListTimeline extends React.PureComponent {
|
|||
multiColumn={multiColumn}
|
||||
>
|
||||
<div className='column-settings__row column-header__links'>
|
||||
<button className='text-btn column-header__setting-btn' tabIndex={0} onClick={this.handleEditClick}>
|
||||
<button type='button' className='text-btn column-header__setting-btn' tabIndex={0} onClick={this.handleEditClick}>
|
||||
<Icon id='pencil' /> <FormattedMessage id='lists.edit' defaultMessage='Edit list' />
|
||||
</button>
|
||||
|
||||
<button className='text-btn column-header__setting-btn' tabIndex={0} onClick={this.handleDeleteClick}>
|
||||
<button type='button' className='text-btn column-header__setting-btn' tabIndex={0} onClick={this.handleDeleteClick}>
|
||||
<Icon id='trash' /> <FormattedMessage id='lists.delete' defaultMessage='Delete list' />
|
||||
</button>
|
||||
</div>
|
||||
|
@ -202,7 +202,7 @@ class ListTimeline extends React.PureComponent {
|
|||
scrollKey={`list_timeline-${columnId}`}
|
||||
timelineId={`list:${id}`}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
emptyMessage={<FormattedMessage id='empty_column.list' defaultMessage='There is nothing in this list yet.' />}
|
||||
emptyMessage={<FormattedMessage id='empty_column.list' defaultMessage='There is nothing in this list yet. When members of this list post new statuses, they will appear here.' />}
|
||||
bindToDocument={!multiColumn}
|
||||
/>
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ export default class LocalSettingsPageItem extends React.PureComponent {
|
|||
const optionElems = options && options.length > 0 && options.map((opt) => {
|
||||
let optionId = `${id}--${opt.value}`;
|
||||
return (
|
||||
<label htmlFor={optionId}>
|
||||
<label key={id} htmlFor={optionId}>
|
||||
<input
|
||||
type='radio'
|
||||
name={id}
|
||||
|
|
|
@ -54,12 +54,11 @@ export default class LocalSettingsPageItem extends React.PureComponent {
|
|||
const optionElems = options && options.length > 0 && options.map((opt) => {
|
||||
let optionId = `${id}--${opt.value}`;
|
||||
return (
|
||||
<label htmlFor={optionId}>
|
||||
<label key={optionId} htmlFor={optionId}>
|
||||
<input
|
||||
type='radio'
|
||||
name={id}
|
||||
id={optionId}
|
||||
key={optionId}
|
||||
value={opt.value}
|
||||
onBlur={handleChange}
|
||||
onChange={handleChange}
|
||||
|
@ -93,7 +92,7 @@ export default class LocalSettingsPageItem extends React.PureComponent {
|
|||
placeholder={placeholder}
|
||||
onChange={handleChange}
|
||||
disabled={!enabled}
|
||||
{...inputProps}
|
||||
{...inputProps}
|
||||
/>
|
||||
</p>
|
||||
</label>
|
||||
|
|
|
@ -2,22 +2,17 @@
|
|||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { HotKeys } from 'react-hotkeys';
|
||||
import classNames from 'classnames';
|
||||
|
||||
// Our imports.
|
||||
import Permalink from 'flavours/glitch/components/permalink';
|
||||
import AccountContainer from 'flavours/glitch/containers/account_container';
|
||||
import NotificationOverlayContainer from '../containers/overlay_container';
|
||||
import Icon from 'flavours/glitch/components/icon';
|
||||
import Report from './report';
|
||||
|
||||
const messages = defineMessages({
|
||||
adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' },
|
||||
});
|
||||
|
||||
export default class AdminReport extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
|
@ -67,7 +62,7 @@ export default class AdminReport extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { intl, account, notification, unread, report } = this.props;
|
||||
const { account, notification, unread, report } = this.props;
|
||||
|
||||
if (!report) {
|
||||
return null;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { makeGetAccount } from 'flavours/glitch/selectors';
|
||||
import FollowRequest from '../components/follow_request';
|
||||
import { authorizeFollowRequest, rejectFollowRequest } from 'flavours/glitch/actions/accounts';
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ import {
|
|||
enterNotificationClearingMode,
|
||||
expandNotifications,
|
||||
scrollTopNotifications,
|
||||
loadPending,
|
||||
mountNotifications,
|
||||
unmountNotifications,
|
||||
loadPending,
|
||||
markNotificationsAsRead,
|
||||
} from 'flavours/glitch/actions/notifications';
|
||||
import { addColumn, removeColumn, moveColumn } from 'flavours/glitch/actions/columns';
|
||||
|
@ -79,16 +79,6 @@ const mapDispatchToProps = dispatch => ({
|
|||
onEnterCleaningMode(yes) {
|
||||
dispatch(enterNotificationClearingMode(yes));
|
||||
},
|
||||
onMarkAsRead() {
|
||||
dispatch(markNotificationsAsRead());
|
||||
dispatch(submitMarkers({ immediate: true }));
|
||||
},
|
||||
onMount() {
|
||||
dispatch(mountNotifications());
|
||||
},
|
||||
onUnmount() {
|
||||
dispatch(unmountNotifications());
|
||||
},
|
||||
dispatch,
|
||||
});
|
||||
|
||||
|
@ -112,8 +102,6 @@ class Notifications extends React.PureComponent {
|
|||
localSettings: ImmutablePropTypes.map,
|
||||
notifCleaningActive: PropTypes.bool,
|
||||
onEnterCleaningMode: PropTypes.func,
|
||||
onMount: PropTypes.func,
|
||||
onUnmount: PropTypes.func,
|
||||
lastReadId: PropTypes.string,
|
||||
canMarkAsRead: PropTypes.bool,
|
||||
needsNotificationPermission: PropTypes.bool,
|
||||
|
@ -127,6 +115,18 @@ class Notifications extends React.PureComponent {
|
|||
animatingNCD: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(mountNotifications());
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this.handleLoadOlder.cancel();
|
||||
this.handleScrollToTop.cancel();
|
||||
this.handleScroll.cancel();
|
||||
// this.props.dispatch(scrollTopNotifications(false));
|
||||
this.props.dispatch(unmountNotifications());
|
||||
}
|
||||
|
||||
handleLoadGap = (maxId) => {
|
||||
this.props.dispatch(expandNotifications({ maxId }));
|
||||
};
|
||||
|
@ -195,20 +195,6 @@ class Notifications extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { onMount } = this.props;
|
||||
if (onMount) {
|
||||
onMount();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
const { onUnmount } = this.props;
|
||||
if (onUnmount) {
|
||||
onUnmount();
|
||||
}
|
||||
}
|
||||
|
||||
handleTransitionEndNCD = () => {
|
||||
this.setState({ animatingNCD: false });
|
||||
};
|
||||
|
@ -219,12 +205,13 @@ class Notifications extends React.PureComponent {
|
|||
};
|
||||
|
||||
handleMarkAsRead = () => {
|
||||
this.props.onMarkAsRead();
|
||||
this.props.dispatch(markNotificationsAsRead());
|
||||
this.props.dispatch(submitMarkers({ immediate: true }));
|
||||
};
|
||||
|
||||
render () {
|
||||
const { intl, notifications, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, showFilterBar, lastReadId, canMarkAsRead, needsNotificationPermission } = this.props;
|
||||
const { notifCleaning, notifCleaningActive } = this.props;
|
||||
const { notifCleaningActive } = this.props;
|
||||
const { animatingNCD } = this.state;
|
||||
const pinned = !!columnId;
|
||||
const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. When other people interact with you, you will see it here." />;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { makeGetAccount } from 'flavours/glitch/selectors';
|
||||
import { injectIntl } from 'react-intl';
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import {
|
||||
|
|
|
@ -554,7 +554,7 @@ class Video extends React.PureComponent {
|
|||
|
||||
playerStyle.height = height;
|
||||
} else if (inline) {
|
||||
return (<div className={computedClass} ref={this.setPlayerRef} tabindex={0} />);
|
||||
return (<div className={computedClass} ref={this.setPlayerRef} tabIndex={0} />);
|
||||
}
|
||||
|
||||
let preload;
|
||||
|
|
|
@ -25,7 +25,7 @@ module Mastodon
|
|||
end
|
||||
|
||||
def suffix_version
|
||||
'+1.0.4'
|
||||
'+1.1.0'
|
||||
end
|
||||
|
||||
def to_a
|
||||
|
|
Loading…
Reference in a new issue