Fix most linter errors

This commit is contained in:
Alex Gleason 2020-04-14 15:45:38 -05:00
parent fc72e39ff4
commit 141b0e6bfa
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
76 changed files with 651 additions and 647 deletions

View file

@ -87,7 +87,7 @@ module.exports = {
'error',
{
vars: 'all',
args: 'after-used',
args: 'none',
ignoreRestSiblings: true,
},
],
@ -183,6 +183,7 @@ module.exports = {
'always',
{
js: 'never',
mjs: 'ignorePackages',
},
],
'import/newline-after-import': 'error',

View file

@ -9,7 +9,7 @@ export const AUTH_LOGGED_OUT = 'AUTH_LOGGED_OUT';
export function createAuthApp() {
return (dispatch, getState) => {
const appToken = getState().getIn(['auth', 'app', 'access_token']);
if (appToken) return; // Skip for now, FIXME: call verify_credentials
if (appToken) return new Promise(_ => _()); // Skip for now, FIXME: call verify_credentials
return api(getState).post('/api/v1/apps', {
// TODO: Add commit hash to client_name
client_name: `SoapboxFE_${(new Date()).toISOString()}`,

View file

@ -9,7 +9,10 @@ export const ME_FETCH_SKIP = 'ME_FETCH_SKIP';
export function fetchMe() {
return (dispatch, getState) => {
const accessToken = getState().getIn(['auth', 'user', 'access_token']);
if (!accessToken) return dispatch({ type: ME_FETCH_SKIP });
if (!accessToken) {
dispatch({ type: ME_FETCH_SKIP });
return;
};
dispatch(fetchMeRequest());
api(getState).get('/api/v1/accounts/verify_credentials').then(response => {
dispatch(fetchMeSuccess(response.data));

View file

@ -126,7 +126,7 @@ export function dequeueNotifications() {
const queuedNotifications = getState().getIn(['notifications', 'queuedNotifications'], ImmutableList());
const totalQueuedNotificationsCount = getState().getIn(['notifications', 'totalQueuedNotificationsCount'], 0);
if (totalQueuedNotificationsCount == 0) {
if (totalQueuedNotificationsCount === 0) {
return;
} else if (totalQueuedNotificationsCount > 0 && totalQueuedNotificationsCount <= MAX_QUEUED_NOTIFICATIONS) {
queuedNotifications.forEach(block => {
@ -264,6 +264,9 @@ export function markReadNotifications() {
type: NOTIFICATIONS_MARK_READ,
notification: top_notification,
});
}).catch(e => {
console.error(e);
console.error('Could not mark notifications read.');
});
}
};

View file

@ -7,8 +7,6 @@ export function fetchFunding() {
return (dispatch, getState) => {
api(getState).get('/patron/v1/funding').then(response => {
dispatch(importFetchedFunding(response.data));
}).then(() => {
dispatch(fetchFundingSuccess());
}).catch(error => {
dispatch(fetchFundingFail(error));
});

View file

@ -3,8 +3,7 @@ import openDB from '../storage/db';
import { evictStatus } from '../storage/modifier';
import { deleteFromTimelines } from './timelines';
import { importFetchedStatus, importFetchedStatuses, importAccount, importStatus } from './importer';
import { ensureComposeIsVisible } from './compose';
import { openModal, closeModal } from './modal';
import { openModal } from './modal';
export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS';

View file

@ -1,6 +1,5 @@
import { Iterable, fromJS } from 'immutable';
import { hydrateCompose } from './compose';
import { importFetchedAccounts } from './importer';
export const STORE_HYDRATE = 'STORE_HYDRATE';
export const STORE_HYDRATE_LAZY = 'STORE_HYDRATE_LAZY';

View file

@ -1,6 +1,6 @@
import { importFetchedStatus, importFetchedStatuses } from './importer';
import api, { getLinks } from '../api';
import { Map as ImmutableMap, List as ImmutableList, toJS } from 'immutable';
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
export const TIMELINE_DELETE = 'TIMELINE_DELETE';
@ -55,7 +55,7 @@ export function dequeueTimeline(timeline, expandFunc, optionalExpandArgs) {
let shouldDispatchDequeue = true;
if (totalQueuedItemsCount == 0) {
if (totalQueuedItemsCount === 0) {
return;
} else if (totalQueuedItemsCount > 0 && totalQueuedItemsCount <= MAX_QUEUED_ITEMS) {
queuedItems.forEach(status => {

View file

@ -84,7 +84,6 @@ class Account extends ImmutablePureComponent {
}
let buttons;
let reciprocal_follow_message;
let followed_by;
if (onActionClick && actionIcon) {

View file

@ -3,7 +3,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
import { injectIntl, defineMessages } from 'react-intl';
import Icon from 'gabsocial/components/icon';
const messages = defineMessages({

View file

@ -1,6 +1,5 @@
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import VerificationBadge from './verification_badge';
import { acctFull } from '../utils/accounts';
@ -9,11 +8,10 @@ export default class DisplayName extends React.PureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
others: ImmutablePropTypes.list,
localDomain: PropTypes.string,
};
render () {
const { others, localDomain } = this.props;
const { others } = this.props;
let displayName, suffix, account;

View file

@ -5,7 +5,7 @@ import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import classNames from 'classnames';
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
import { injectIntl, defineMessages } from 'react-intl';
import { Link } from 'react-router-dom';
import Icon from 'gabsocial/components/icon';
import { fetchLists } from 'gabsocial/actions/lists';

View file

@ -16,7 +16,7 @@ export default class Icon extends React.PureComponent {
// tag. There is a common adblocker rule which hides elements with
// alt='retweet' unless the domain is twitter.com. This should
// change what screenreaders call it as well.
var alt_id = (id == 'retweet') ? 'repost' : id;
var alt_id = (id === 'retweet') ? 'repost' : id;
return (
<i role='img' alt={alt_id} className={classNames('fa', `fa-${id}`, className, { 'fa-fw': fixedWidth })} {...other} />
);

View file

@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'gabsocial/components/icon';
import { shortNumberFormat } from 'gabsocial/utils/numbers';
const IconWithBadge = ({ id, count, className }) => {

View file

@ -108,9 +108,7 @@ class Item extends React.PureComponent {
}
render () {
const { attachment, index, size, standalone, displayWidth, visible, dimensions } = this.props;
const ar = attachment.getIn(['meta', 'small', 'aspect']);
const { attachment, standalone, displayWidth, visible, dimensions } = this.props;
let width = 100;
let height = '100%';
@ -285,14 +283,11 @@ class MediaGallery extends React.PureComponent {
const style = {};
const size = media.take(4).size;
const standard169 = width / (16 / 9);
const standard169_percent = 100 / (16 / 9);
const standard169_px = `${standard169}px`;
const panoSize = Math.floor(width / maximumAspectRatio);
const panoSize_px = `${Math.floor(width / maximumAspectRatio)}px`;
let itemsDimensions = [];
if (size == 1 && width) {
if (size === 1 && width) {
const aspectRatio = media.getIn([0, 'meta', 'small', 'aspect']);
if (isPanoramic(aspectRatio)) {
@ -308,7 +303,7 @@ class MediaGallery extends React.PureComponent {
const ar3 = media.getIn([2, 'meta', 'small', 'aspect']);
const ar4 = media.getIn([3, 'meta', 'small', 'aspect']);
if (size == 2) {
if (size === 2) {
if (isPortrait(ar1) && isPortrait(ar2)) {
style.height = width - (width / maximumAspectRatio);
} else if (isPanoramic(ar1) && isPanoramic(ar2)) {
@ -358,7 +353,7 @@ class MediaGallery extends React.PureComponent {
{ w: 50, h: '100%', l: '2px' },
];
}
} else if (size == 3) {
} else if (size === 3) {
if (isPanoramic(ar1) && isPanoramic(ar2) && isPanoramic(ar3)) {
style.height = panoSize * 3;
} else if (isPortrait(ar1) && isPortrait(ar2) && isPortrait(ar3)) {
@ -427,7 +422,7 @@ class MediaGallery extends React.PureComponent {
{ w: 100, h: '50%', t: '2px' },
];
}
} else if (size == 4) {
} else if (size === 4) {
if (
(isPortrait(ar1) && isPortrait(ar2) && isPortrait(ar3) && isPortrait(ar4)) ||
(isPortrait(ar1) && isPortrait(ar2) && isPortrait(ar3) && isNonConformingRatio(ar4)) ||

View file

@ -48,9 +48,9 @@ class ModalRoot extends React.PureComponent {
}
handleOnClose = () => {
const { onOpenModal, composeText, onClose, intl, type, onCancelReplyCompose } = this.props;
const { onOpenModal, composeText, intl, type, onCancelReplyCompose } = this.props;
if (composeText && type == 'COMPOSE') {
if (composeText && type === 'COMPOSE') {
onOpenModal('CONFIRM', {
message: <FormattedMessage id='confirmations.delete.message' defaultMessage='Are you sure you want to delete this post?' />,
confirm: intl.formatMessage(messages.confirm),
@ -117,7 +117,7 @@ class ModalRoot extends React.PureComponent {
return (
<div className='modal-root' ref={this.setRef} style={{ opacity: revealed ? 1 : 0 }}>
<div style={{ pointerEvents: visible ? 'auto' : 'none' }}>
<div role='presentation' className='modal-root__overlay' onClick={() => this.handleOnClose()} />
<div role='presentation' className='modal-root__overlay' onClick={this.handleOnClose} />
<div role='dialog' className='modal-root__container'>{children}</div>
</div>
</div>

View file

@ -5,7 +5,6 @@ import LoadMore from './load_more';
import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper';
import { throttle } from 'lodash';
import { List as ImmutableList } from 'immutable';
import classNames from 'classnames';
import LoadingIndicator from './loading_indicator';
const MOUSE_IDLE_DELAY = 300;

View file

@ -245,7 +245,7 @@ class StatusActionBar extends ImmutablePureComponent {
}
render () {
const { status, intl, withDismiss } = this.props;
const { status, intl } = this.props;
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));

View file

@ -136,7 +136,7 @@ export default class StatusContent extends React.PureComponent {
}
getHtmlContent = () => {
const { status, reblogContent } = this.props;
const { status } = this.props;
const properContent = status.get('contentHtml');
@ -144,7 +144,7 @@ export default class StatusContent extends React.PureComponent {
}
render () {
const { status, reblogContent } = this.props;
const { status } = this.props;
if (status.get('content').length === 0) {
return null;

View file

@ -32,7 +32,7 @@ export default class TimelineQueueButtonHeader extends React.PureComponent {
defaultMessage='Click to see {count} new {type}'
values={{
count: shortNumberFormat(count),
type: count == 1 ? itemType : `${itemType}s`,
type: count === 1 ? itemType : `${itemType}s`,
}}
/>}
</a>

View file

@ -1,5 +1,4 @@
import React from 'react';
import Icon from './icon';
const VerificationBadge = () => (
<span className='verified-icon'>

View file

@ -8,7 +8,7 @@ import { INTRODUCTION_VERSION } from '../actions/onboarding';
import { Switch, BrowserRouter, Route } from 'react-router-dom';
import { ScrollContext } from 'react-router-scroll-4';
import UI from '../features/ui';
import Introduction from '../features/introduction';
// import Introduction from '../features/introduction';
import { fetchCustomEmojis } from '../actions/custom_emojis';
import { hydrateStore } from '../actions/store';
import { IntlProvider, addLocaleData } from 'react-intl';
@ -52,7 +52,7 @@ class GabSocialMount extends React.PureComponent {
render () {
const { me } = this.props;
if (me == null) return null;
if (me === null) return null;
// Disabling introduction for launch
// const { showIntroduction } = this.props;

View file

@ -9,7 +9,6 @@ import Button from 'gabsocial/components/button';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { autoPlayGif, isStaff } from 'gabsocial/initial_state';
import classNames from 'classnames';
import Icon from 'gabsocial/components/icon';
import Avatar from 'gabsocial/components/avatar';
import { shortNumberFormat } from 'gabsocial/utils/numbers';
import { NavLink } from 'react-router-dom';
@ -48,15 +47,6 @@ const messages = defineMessages({
add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
});
const dateFormatOptions = {
month: 'short',
day: 'numeric',
year: 'numeric',
hour12: false,
hour: '2-digit',
minute: '2-digit',
};
const mapStateToProps = state => {
return {
me: state.get('me'),
@ -108,7 +98,7 @@ class Header extends ImmutablePureComponent {
});
makeMenu() {
const { account, intl, domain, me } = this.props;
const { account, intl, me } = this.props;
let menu = [];
@ -180,7 +170,7 @@ class Header extends ImmutablePureComponent {
}
makeInfo() {
const { account, intl, me } = this.props;
const { account, me } = this.props;
let info = [];
@ -224,7 +214,7 @@ class Header extends ImmutablePureComponent {
};
render () {
const { account, intl, domain, username, me } = this.props;
const { account, intl, username, me } = this.props;
const { isSmallScreen } = this.state;
if (!account) {
@ -250,10 +240,6 @@ class Header extends ImmutablePureComponent {
const actionBtn = this.getActionBtn();
const menu = this.makeMenu();
const content = { __html: account.get('note_emojified') };
const fields = account.get('fields');
const acct = account.get('acct').indexOf('@') === -1 && domain ? `${account.get('acct')}@${domain}` : account.get('acct');
const headerImgSrc = autoPlayGif ? account.get('header') : account.get('header_static');
const headerMissing = (headerImgSrc.indexOf('/headers/original/missing.png') > -1);

View file

@ -21,14 +21,14 @@ import { FormattedMessage } from 'react-intl';
const mapStateToProps = (state, { params: { username }, withReplies = false }) => {
const me = state.get('me');
const accounts = state.getIn(['accounts']);
const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() == username.toLowerCase());
const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() === username.toLowerCase());
let accountId = -1;
let accountUsername = username;
if (accountFetchError) {
accountId = null;
} else {
let account = accounts.find(acct => username.toLowerCase() == acct.getIn(['acct'], '').toLowerCase());
let account = accounts.find(acct => username.toLowerCase() === acct.getIn(['acct'], '').toLowerCase());
accountId = account ? account.getIn(['id'], null) : -1;
accountUsername = account ? account.getIn(['acct'], '') : '';
}
@ -36,7 +36,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
const isBlocked = state.getIn(['relationships', accountId, 'blocked_by'], false);
const isLocked = state.getIn(['accounts', accountId, 'locked'], false);
const isFollowing = state.getIn(['relationships', accountId, 'following'], false);
const unavailable = (me == accountId) ? false : (isBlocked || (isLocked && !isFollowing));
const unavailable = (me === accountId) ? false : (isBlocked || (isLocked && !isFollowing));
return {
accountId,
@ -89,7 +89,7 @@ class AccountGallery extends ImmutablePureComponent {
};
componentDidMount () {
const { params: { username }, accountId, withReplies } = this.props;
const { params: { username }, accountId } = this.props;
if (accountId && accountId !== -1) {
this.props.dispatch(fetchAccount(accountId));
@ -161,7 +161,7 @@ class AccountGallery extends ImmutablePureComponent {
);
}
if (accountId == -1 || (!attachments && isLoading)) {
if (accountId === -1 || (!attachments && isLoading)) {
return (
<Column>
<LoadingIndicator />
@ -210,7 +210,7 @@ class AccountGallery extends ImmutablePureComponent {
))}
{
attachments.size == 0 &&
attachments.size === 0 &&
<div className='empty-column-indicator'>
<FormattedMessage id='account_gallery.none' defaultMessage='No media to show.' />
</div>

View file

@ -4,8 +4,6 @@ import PropTypes from 'prop-types';
import InnerHeader from '../../account/components/header';
import ImmutablePureComponent from 'react-immutable-pure-component';
import MovedNote from './moved_note';
import { FormattedMessage } from 'react-intl';
import { NavLink } from 'react-router-dom';
export default class Header extends ImmutablePureComponent {

View file

@ -19,14 +19,14 @@ const emptyList = ImmutableList();
const mapStateToProps = (state, { params: { username }, withReplies = false }) => {
const me = state.get('me');
const accounts = state.getIn(['accounts']);
const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() == username.toLowerCase());
const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() === username.toLowerCase());
let accountId = -1;
let accountUsername = username;
if (accountFetchError) {
accountId = null;
} else {
let account = accounts.find(acct => username.toLowerCase() == acct.getIn(['acct'], '').toLowerCase());
let account = accounts.find(acct => username.toLowerCase() === acct.getIn(['acct'], '').toLowerCase());
accountId = account ? account.getIn(['id'], null) : -1;
accountUsername = account ? account.getIn(['acct'], '') : '';
}
@ -36,7 +36,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
const isBlocked = state.getIn(['relationships', accountId, 'blocked_by'], false);
const isLocked = state.getIn(['accounts', accountId, 'locked'], false);
const isFollowing = state.getIn(['relationships', accountId, 'following'], false);
const unavailable = (me == accountId) ? false : (isBlocked || (isLocked && !isFollowing));
const unavailable = (me === accountId) ? false : (isBlocked || (isLocked && !isFollowing));
return {
accountId,
@ -114,7 +114,7 @@ class AccountTimeline extends ImmutablePureComponent {
);
}
if (accountId == -1 || (!statusIds && isLoading)) {
if (accountId === -1 || (!statusIds && isLoading)) {
return (
<Column>
<LoadingIndicator />

View file

@ -6,14 +6,8 @@ import StatusListContainer from '../ui/containers/status_list_container';
import Column from '../../components/column';
import ColumnSettingsContainer from './containers/column_settings_container';
import HomeColumnHeader from '../../components/home_column_header';
import {
expandCommunityTimeline,
expandPublicTimeline,
} from '../../actions/timelines';
import {
connectCommunityStream,
connectPublicStream,
} from '../../actions/streaming';
import { expandCommunityTimeline } from '../../actions/timelines';
import { connectCommunityStream } from '../../actions/streaming';
const messages = defineMessages({
title: { id: 'column.community', defaultMessage: 'Local timeline' },

View file

@ -1,7 +1,6 @@
import React from 'react';
import { connect } from 'react-redux';
import { openModal } from '../../../actions/modal';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
import { defineMessages, injectIntl } from 'react-intl';
@ -43,7 +42,7 @@ class ActionBar extends React.PureComponent {
}
render () {
const { intl, onOpenHotkeys, onClickLogOut } = this.props;
const { intl, onClickLogOut } = this.props;
const size = this.props.size || 16;
let menu = [];

View file

@ -100,7 +100,7 @@ class ComposeForm extends ImmutablePureComponent {
}
handleClick = (e) => {
if (!this.form) return false;
if (!this.form) return;
if (!this.form.contains(e.target)) {
this.handleClickOutside();
}

View file

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import { FormattedMessage, injectIntl } from 'react-intl';
import AccountContainer from '../../../containers/account_container';
import StatusContainer from '../../../containers/status_container';
import ImmutablePureComponent from 'react-immutable-pure-component';
@ -23,7 +23,7 @@ class SearchResults extends ImmutablePureComponent {
}
render () {
const { intl, results, dismissSuggestion } = this.props;
const { results } = this.props;
const { isSmallScreen } = this.state;
if (results.isEmpty() && isSmallScreen) {

View file

@ -4,7 +4,6 @@ import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { fetchFavouritedStatuses, expandFavouritedStatuses } from '../../actions/favourites';
import Column from '../ui/components/column';
import ColumnHeader from '../../components/column_header';
import StatusList from '../../components/status_list';
import { injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
@ -43,7 +42,7 @@ class Favourites extends ImmutablePureComponent {
}, 300, { leading: true })
render () {
const { intl, statusIds, hasMore, isLoading, isMyAccount } = this.props;
const { statusIds, hasMore, isLoading, isMyAccount } = this.props;
if (!isMyAccount) {
return (

View file

@ -20,21 +20,20 @@ import MissingIndicator from 'gabsocial/components/missing_indicator';
const mapStateToProps = (state, { params: { username }, withReplies = false }) => {
const me = state.get('me');
const accounts = state.getIn(['accounts']);
const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() == username.toLowerCase());
const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() === username.toLowerCase());
let accountId = -1;
let accountUsername = username;
if (accountFetchError) {
accountId = null;
} else {
let account = accounts.find(acct => username.toLowerCase() == acct.getIn(['acct'], '').toLowerCase());
let account = accounts.find(acct => username.toLowerCase() === acct.getIn(['acct'], '').toLowerCase());
accountId = account ? account.getIn(['id'], null) : -1;
}
const isBlocked = state.getIn(['relationships', accountId, 'blocked_by'], false);
const isLocked = state.getIn(['accounts', accountId, 'locked'], false);
const isFollowing = state.getIn(['relationships', accountId, 'following'], false);
const unavailable = (me == accountId) ? false : (isBlocked || (isLocked && !isFollowing));
const unavailable = (me === accountId) ? false : (isBlocked || (isLocked && !isFollowing));
return {
accountId,
@ -58,7 +57,7 @@ class Followers extends ImmutablePureComponent {
};
componentWillMount () {
const { params: { username }, accountId, withReplies } = this.props;
const { params: { username }, accountId } = this.props;
if (accountId && accountId !== -1) {
this.props.dispatch(fetchAccount(accountId));
@ -92,7 +91,7 @@ class Followers extends ImmutablePureComponent {
);
}
if (accountId == -1 || (!accountIds)) {
if (accountId === -1 || (!accountIds)) {
return (
<Column>
<LoadingIndicator />

View file

@ -14,27 +14,26 @@ import {
import { FormattedMessage } from 'react-intl';
import AccountContainer from '../../containers/account_container';
import Column from '../ui/components/column';
import HeaderContainer from '../account_timeline/containers/header_container';
import ScrollableList from '../../components/scrollable_list';
import MissingIndicator from 'gabsocial/components/missing_indicator';
const mapStateToProps = (state, { params: { username }, withReplies = false }) => {
const me = state.get('me');
const accounts = state.getIn(['accounts']);
const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() == username.toLowerCase());
const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() === username.toLowerCase());
let accountId = -1;
if (accountFetchError) {
accountId = null;
} else {
let account = accounts.find(acct => username.toLowerCase() == acct.getIn(['acct'], '').toLowerCase());
let account = accounts.find(acct => username.toLowerCase() === acct.getIn(['acct'], '').toLowerCase());
accountId = account ? account.getIn(['id'], null) : -1;
}
const isBlocked = state.getIn(['relationships', accountId, 'blocked_by'], false);
const isLocked = state.getIn(['accounts', accountId, 'locked'], false);
const isFollowing = state.getIn(['relationships', accountId, 'following'], false);
const unavailable = (me == accountId) ? false : (isBlocked || (isLocked && !isFollowing));
const unavailable = (me === accountId) ? false : (isBlocked || (isLocked && !isFollowing));
return {
accountId,
@ -58,7 +57,7 @@ class Following extends ImmutablePureComponent {
};
componentWillMount () {
const { params: { username }, accountId, withReplies } = this.props;
const { params: { username }, accountId } = this.props;
if (accountId && accountId !== -1) {
this.props.dispatch(fetchAccount(accountId));
@ -92,7 +91,7 @@ class Following extends ImmutablePureComponent {
);
}
if (accountId == -1 || (!accountIds)) {
if (accountId === -1 || (!accountIds)) {
return (
<Column>
<LoadingIndicator />

View file

@ -2,7 +2,6 @@ import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { changeValue, submit, reset } from '../../../actions/group_editor';
import Icon from '../../../components/icon';
import { defineMessages, injectIntl } from 'react-intl';
import classNames from 'classnames';
@ -33,81 +32,81 @@ export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class Create extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
}
static contextTypes = {
router: PropTypes.object,
}
static propTypes = {
title: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
coverImage: PropTypes.object,
disabled: PropTypes.bool,
intl: PropTypes.object.isRequired,
onTitleChange: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
};
static propTypes = {
title: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
coverImage: PropTypes.object,
disabled: PropTypes.bool,
intl: PropTypes.object.isRequired,
onTitleChange: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
};
componentWillMount() {
this.props.reset();
}
componentWillMount() {
this.props.reset();
}
handleTitleChange = e => {
this.props.onTitleChange(e.target.value);
}
handleTitleChange = e => {
this.props.onTitleChange(e.target.value);
}
handleDescriptionChange = e => {
this.props.onDescriptionChange(e.target.value);
}
handleDescriptionChange = e => {
this.props.onDescriptionChange(e.target.value);
}
handleCoverImageChange = e => {
this.props.onCoverImageChange(e.target.files[0]);
}
handleCoverImageChange = e => {
this.props.onCoverImageChange(e.target.files[0]);
}
handleSubmit = e => {
e.preventDefault();
this.props.onSubmit(this.context.router.history);
}
handleSubmit = e => {
e.preventDefault();
this.props.onSubmit(this.context.router.history);
}
render () {
const { title, description, coverImage, disabled, intl } = this.props;
render () {
const { title, description, coverImage, disabled, intl } = this.props;
return (
<form className='group-form' onSubmit={this.handleSubmit}>
<div>
<input
className='standard'
type='text'
value={title}
disabled={disabled}
onChange={this.handleTitleChange}
placeholder={intl.formatMessage(messages.title)}
/>
</div>
<div>
<textarea
className='standard'
type='text'
value={description}
disabled={disabled}
onChange={this.handleDescriptionChange}
placeholder={intl.formatMessage(messages.description)}
/>
</div>
<div>
<label htmlFor='group_cover_image' className={classNames('group-form__file-label', { 'group-form__file-label--selected': coverImage !== null })}>
{intl.formatMessage(coverImage === null ? messages.coverImage : messages.coverImageChange)}
</label>
<input
type='file'
className='group-form__file'
id='group_cover_image'
disabled={disabled}
onChange={this.handleCoverImageChange}
/>
<button className='standard-small'>{intl.formatMessage(messages.create)}</button>
</div>
</form>
);
}
return (
<form className='group-form' onSubmit={this.handleSubmit}>
<div>
<input
className='standard'
type='text'
value={title}
disabled={disabled}
onChange={this.handleTitleChange}
placeholder={intl.formatMessage(messages.title)}
/>
</div>
<div>
<textarea
className='standard'
type='text'
value={description}
disabled={disabled}
onChange={this.handleDescriptionChange}
placeholder={intl.formatMessage(messages.description)}
/>
</div>
<div>
<label htmlFor='group_cover_image' className={classNames('group-form__file-label', { 'group-form__file-label--selected': coverImage !== null })}>
{intl.formatMessage(coverImage === null ? messages.coverImage : messages.coverImageChange)}
</label>
<input
type='file'
className='group-form__file'
id='group_cover_image'
disabled={disabled}
onChange={this.handleCoverImageChange}
/>
<button className='standard-small'>{intl.formatMessage(messages.create)}</button>
</div>
</form>
);
}
}

View file

@ -3,9 +3,9 @@ import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { changeValue, submit, setUp } from '../../../actions/group_editor';
import Icon from '../../../components/icon';
import { defineMessages, injectIntl } from 'react-intl';
import LoadingIndicator from '../../../components/loading_indicator';
import MissingIndicator from 'gabsocial/components/missing_indicator';
import Column from '../../../components/column';
import classNames from 'classnames';
@ -37,112 +37,112 @@ export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl
class Edit extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
}
static contextTypes = {
router: PropTypes.object,
}
static propTypes = {
group: ImmutablePropTypes.map,
title: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
coverImage: PropTypes.object,
disabled: PropTypes.bool,
intl: PropTypes.object.isRequired,
onTitleChange: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
};
static propTypes = {
group: ImmutablePropTypes.map,
title: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
coverImage: PropTypes.object,
disabled: PropTypes.bool,
intl: PropTypes.object.isRequired,
onTitleChange: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
};
componentWillMount(nextProps) {
if (this.props.group) {
this.props.setUp(this.props.group);
}
}
componentWillMount(nextProps) {
if (this.props.group) {
this.props.setUp(this.props.group);
}
}
componentWillReceiveProps(nextProps) {
if (!this.props.group && nextProps.group) {
this.props.setUp(nextProps.group);
}
}
componentWillReceiveProps(nextProps) {
if (!this.props.group && nextProps.group) {
this.props.setUp(nextProps.group);
}
}
handleTitleChange = e => {
this.props.onTitleChange(e.target.value);
}
handleTitleChange = e => {
this.props.onTitleChange(e.target.value);
}
handleDescriptionChange = e => {
this.props.onDescriptionChange(e.target.value);
}
handleDescriptionChange = e => {
this.props.onDescriptionChange(e.target.value);
}
handleCoverImageChange = e => {
this.props.onCoverImageChange(e.target.files[0]);
}
handleCoverImageChange = e => {
this.props.onCoverImageChange(e.target.files[0]);
}
handleSubmit = e => {
e.preventDefault();
this.props.onSubmit(this.context.router.history);
}
handleSubmit = e => {
e.preventDefault();
this.props.onSubmit(this.context.router.history);
}
handleClick = () => {
this.props.onSubmit(this.context.router.history);
}
handleClick = () => {
this.props.onSubmit(this.context.router.history);
}
render () {
const { group, title, description, coverImage, disabled, intl } = this.props;
render () {
const { group, title, description, coverImage, disabled, intl } = this.props;
if (typeof group === 'undefined') {
return (
<Column>
<LoadingIndicator />
</Column>
);
} else if (group === false) {
return (
<Column>
<MissingIndicator />
</Column>
);
}
if (typeof group === 'undefined') {
return (
<Column>
<LoadingIndicator />
</Column>
);
} else if (group === false) {
return (
<Column>
<MissingIndicator />
</Column>
);
}
return (
<form className='group-form' onSubmit={this.handleSubmit}>
<div>
<input
className='standard'
type='text'
value={title}
disabled={disabled}
onChange={this.handleTitleChange}
placeholder={intl.formatMessage(messages.title)}
/>
</div>
return (
<form className='group-form' onSubmit={this.handleSubmit}>
<div>
<input
className='standard'
type='text'
value={title}
disabled={disabled}
onChange={this.handleTitleChange}
placeholder={intl.formatMessage(messages.title)}
/>
</div>
<div>
<textarea
className='standard'
type='text'
value={description}
disabled={disabled}
onChange={this.handleDescriptionChange}
placeholder={intl.formatMessage(messages.description)}
/>
</div>
<div>
<textarea
className='standard'
type='text'
value={description}
disabled={disabled}
onChange={this.handleDescriptionChange}
placeholder={intl.formatMessage(messages.description)}
/>
</div>
<div>
<label htmlFor='group_cover_image' className={classNames('group-form__file-label', { 'group-form__file-label--selected': coverImage !== null })}>
{intl.formatMessage(coverImage === null ? messages.coverImage : messages.coverImageChange)}
</label>
<div>
<label htmlFor='group_cover_image' className={classNames('group-form__file-label', { 'group-form__file-label--selected': coverImage !== null })}>
{intl.formatMessage(coverImage === null ? messages.coverImage : messages.coverImageChange)}
</label>
<input
type='file'
className='group-form__file'
id='group_cover_image'
disabled={disabled}
onChange={this.handleCoverImageChange}
/>
<input
type='file'
className='group-form__file'
id='group_cover_image'
disabled={disabled}
onChange={this.handleCoverImageChange}
/>
<button>{intl.formatMessage(messages.update)}</button>
</div>
</form>
);
}
<button>{intl.formatMessage(messages.update)}</button>
</div>
</form>
);
}
}

View file

@ -31,9 +31,9 @@ class GroupCard extends ImmutablePureComponent {
getRole() {
const { intl, relationships } = this.props;
if (!relationships) return null;
if (relationships.get('admin')) return intl.formatMessage(messages.role_admin);
if (relationships.get('member')) return intl.formatMessage(messages.role_member);
return null;
}
render() {
@ -53,4 +53,4 @@ class GroupCard extends ImmutablePureComponent {
);
}
}
}

View file

@ -26,66 +26,66 @@ export default @connect(mapStateToProps)
@injectIntl
class Groups extends ImmutablePureComponent {
static propTypes = {
params: PropTypes.object.isRequired,
activeTab: PropTypes.string.isRequired,
showCreateForm: PropTypes.bool,
dispatch: PropTypes.func.isRequired,
groups: ImmutablePropTypes.map,
groupIds: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
};
static propTypes = {
params: PropTypes.object.isRequired,
activeTab: PropTypes.string.isRequired,
showCreateForm: PropTypes.bool,
dispatch: PropTypes.func.isRequired,
groups: ImmutablePropTypes.map,
groupIds: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
};
componentWillMount () {
this.props.dispatch(fetchGroups(this.props.activeTab));
}
componentWillMount () {
this.props.dispatch(fetchGroups(this.props.activeTab));
}
componentDidUpdate(oldProps) {
if (this.props.activeTab && this.props.activeTab !== oldProps.activeTab) {
this.props.dispatch(fetchGroups(this.props.activeTab));
}
}
componentDidUpdate(oldProps) {
if (this.props.activeTab && this.props.activeTab !== oldProps.activeTab) {
this.props.dispatch(fetchGroups(this.props.activeTab));
}
}
renderHeader() {
const { intl, activeTab } = this.props;
renderHeader() {
const { intl, activeTab } = this.props;
return (
<div className='group-column-header'>
<div className='group-column-header__cta'><Link to='/groups/create' className='button standard-small'>{intl.formatMessage(messages.create)}</Link></div>
<div className='group-column-header__title'>{intl.formatMessage(messages.heading)}</div>
return (
<div className='group-column-header'>
<div className='group-column-header__cta'><Link to='/groups/create' className='button standard-small'>{intl.formatMessage(messages.create)}</Link></div>
<div className='group-column-header__title'>{intl.formatMessage(messages.heading)}</div>
<div className='column-header__wrapper'>
<h1 className='column-header'>
<Link to='/groups' className={classNames('btn grouped', { 'active': 'featured' === activeTab })}>
{intl.formatMessage(messages.tab_featured)}
</Link>
<div className='column-header__wrapper'>
<h1 className='column-header'>
<Link to='/groups' className={classNames('btn grouped', { 'active': 'featured' === activeTab })}>
{intl.formatMessage(messages.tab_featured)}
</Link>
<Link to='/groups/browse/member' className={classNames('btn grouped', { 'active': 'member' === activeTab })}>
{intl.formatMessage(messages.tab_member)}
</Link>
<Link to='/groups/browse/member' className={classNames('btn grouped', { 'active': 'member' === activeTab })}>
{intl.formatMessage(messages.tab_member)}
</Link>
<Link to='/groups/browse/admin' className={classNames('btn grouped', { 'active': 'admin' === activeTab })}>
{intl.formatMessage(messages.tab_admin)}
</Link>
</h1>
</div>
</div>
);
}
<Link to='/groups/browse/admin' className={classNames('btn grouped', { 'active': 'admin' === activeTab })}>
{intl.formatMessage(messages.tab_admin)}
</Link>
</h1>
</div>
</div>
);
}
render () {
const { groupIds, showCreateForm } = this.props;
render () {
const { groupIds, showCreateForm } = this.props;
return (
<div>
{!showCreateForm && this.renderHeader()}
{showCreateForm && <GroupCreate /> }
return (
<div>
{!showCreateForm && this.renderHeader()}
{showCreateForm && <GroupCreate /> }
<div className='group-card-list'>
{groupIds.map(id => <GroupCard key={id} id={id} />)}
</div>
</div>
);
}
<div className='group-card-list'>
{groupIds.map(id => <GroupCard key={id} id={id} />)}
</div>
</div>
);
}
}
}

View file

@ -23,52 +23,52 @@ const mapStateToProps = (state, { params: { id } }) => ({
export default @connect(mapStateToProps)
class GroupMembers extends ImmutablePureComponent {
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
};
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
};
componentWillMount () {
const { params: { id } } = this.props;
componentWillMount () {
const { params: { id } } = this.props;
this.props.dispatch(fetchMembers(id));
}
this.props.dispatch(fetchMembers(id));
}
componentWillReceiveProps (nextProps) {
if (nextProps.params.id !== this.props.params.id) {
this.props.dispatch(fetchMembers(nextProps.params.id));
}
}
componentWillReceiveProps (nextProps) {
if (nextProps.params.id !== this.props.params.id) {
this.props.dispatch(fetchMembers(nextProps.params.id));
}
}
handleLoadMore = debounce(() => {
this.props.dispatch(expandMembers(this.props.params.id));
}, 300, { leading: true });
handleLoadMore = debounce(() => {
this.props.dispatch(expandMembers(this.props.params.id));
}, 300, { leading: true });
render () {
const { accountIds, hasMore, group } = this.props;
render () {
const { accountIds, hasMore, group } = this.props;
if (!group || !accountIds) {
return (
<Column>
<LoadingIndicator />
</Column>
);
}
if (!group || !accountIds) {
return (
<Column>
<LoadingIndicator />
</Column>
);
}
return (
<Column>
<ScrollableList
scrollKey='members'
hasMore={hasMore}
onLoadMore={this.handleLoadMore}
emptyMessage={<FormattedMessage id='group.members.empty' defaultMessage='This group does not has any members.' />}
>
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
</ScrollableList>
</Column>
);
}
return (
<Column>
<ScrollableList
scrollKey='members'
hasMore={hasMore}
onLoadMore={this.handleLoadMore}
emptyMessage={<FormattedMessage id='group.members.empty' defaultMessage='This group does not has any members.' />}
>
{accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
</ScrollableList>
</Column>
);
}
}

View file

@ -30,58 +30,58 @@ export default @connect(mapStateToProps)
@injectIntl
class GroupRemovedAccounts extends ImmutablePureComponent {
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
};
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
};
componentWillMount () {
const { params: { id } } = this.props;
componentWillMount () {
const { params: { id } } = this.props;
this.props.dispatch(fetchRemovedAccounts(id));
}
this.props.dispatch(fetchRemovedAccounts(id));
}
componentWillReceiveProps (nextProps) {
if (nextProps.params.id !== this.props.params.id) {
this.props.dispatch(fetchRemovedAccounts(nextProps.params.id));
}
}
componentWillReceiveProps (nextProps) {
if (nextProps.params.id !== this.props.params.id) {
this.props.dispatch(fetchRemovedAccounts(nextProps.params.id));
}
}
handleLoadMore = debounce(() => {
this.props.dispatch(expandRemovedAccounts(this.props.params.id));
}, 300, { leading: true });
handleLoadMore = debounce(() => {
this.props.dispatch(expandRemovedAccounts(this.props.params.id));
}, 300, { leading: true });
render () {
const { accountIds, hasMore, group, intl } = this.props;
render () {
const { accountIds, hasMore, group, intl } = this.props;
if (!group || !accountIds) {
return (
<Column>
<LoadingIndicator />
</Column>
);
}
if (!group || !accountIds) {
return (
<Column>
<LoadingIndicator />
</Column>
);
}
return (
<Column>
<ScrollableList
scrollKey='removed_accounts'
hasMore={hasMore}
onLoadMore={this.handleLoadMore}
emptyMessage={<FormattedMessage id='group.removed_accounts.empty' defaultMessage='This group does not has any removed accounts.' />}
>
{accountIds.map(id => (<AccountContainer
key={id}
id={id}
actionIcon='remove'
onActionClick={() => this.props.dispatch(removeRemovedAccount(group.get('id'), id))}
actionTitle={intl.formatMessage(messages.remove)}
/>))}
</ScrollableList>
</Column>
);
}
return (
<Column>
<ScrollableList
scrollKey='removed_accounts'
hasMore={hasMore}
onLoadMore={this.handleLoadMore}
emptyMessage={<FormattedMessage id='group.removed_accounts.empty' defaultMessage='This group does not has any removed accounts.' />}
>
{accountIds.map(id => (<AccountContainer
key={id}
id={id}
actionIcon='remove'
onActionClick={() => this.props.dispatch(removeRemovedAccount(group.get('id'), id))}
actionTitle={intl.formatMessage(messages.remove)}
/>))}
</ScrollableList>
</Column>
);
}
}

View file

@ -17,63 +17,65 @@ const messages = defineMessages({
export default @injectIntl
class Header extends ImmutablePureComponent {
static propTypes = {
group: ImmutablePropTypes.map,
relationships: ImmutablePropTypes.map,
toggleMembership: PropTypes.func.isRequired,
};
static propTypes = {
group: ImmutablePropTypes.map,
relationships: ImmutablePropTypes.map,
toggleMembership: PropTypes.func.isRequired,
};
static contextTypes = {
router: PropTypes.object,
};
static contextTypes = {
router: PropTypes.object,
};
getActionButton() {
const { group, relationships, toggleMembership, intl } = this.props;
const toggle = () => toggleMembership(group, relationships);
getActionButton() {
const { group, relationships, toggleMembership, intl } = this.props;
const toggle = () => toggleMembership(group, relationships);
if (!relationships) {
return '';
} else if (!relationships.get('member')) {
return <Button className='logo-button' text={intl.formatMessage(messages.join)} onClick={toggle} />;
} else if (relationships.get('member')) {
return <Button className='logo-button' text={intl.formatMessage(messages.leave, { name: group.get('title') })} onClick={toggle} />;
}
}
if (!relationships) {
return '';
} else if (!relationships.get('member')) {
return <Button className='logo-button' text={intl.formatMessage(messages.join)} onClick={toggle} />;
} else if (relationships.get('member')) {
return <Button className='logo-button' text={intl.formatMessage(messages.leave, { name: group.get('title') })} onClick={toggle} />;
}
getAdminMenu() {
const { group, intl } = this.props;
return '';
}
const menu = [
{ text: intl.formatMessage(messages.edit), to: `/groups/${group.get('id')}/edit` },
{ text: intl.formatMessage(messages.removed_accounts), to: `/groups/${group.get('id')}/removed_accounts` },
];
getAdminMenu() {
const { group, intl } = this.props;
return <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />;
}
const menu = [
{ text: intl.formatMessage(messages.edit), to: `/groups/${group.get('id')}/edit` },
{ text: intl.formatMessage(messages.removed_accounts), to: `/groups/${group.get('id')}/removed_accounts` },
];
render () {
const { group, relationships } = this.props;
return <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />;
}
if (!group || !relationships) {
return null;
}
render () {
const { group, relationships } = this.props;
return (
<div className='group__header-container'>
<div className='group__header'>
<div className='group__cover'>
<img src={group.get('cover_image_url')} alt='' className='parallax' />
</div>
if (!group || !relationships) {
return null;
}
<div className='group__tabs'>
<NavLink exact className='group__tabs__tab' activeClassName='group__tabs__tab--active' to={`/groups/${group.get('id')}`}>Posts</NavLink>
<NavLink exact className='group__tabs__tab' activeClassName='group__tabs__tab--active' to={`/groups/${group.get('id')}/members`}>Members</NavLink>
{this.getActionButton()}
{relationships.get('admin') && this.getAdminMenu()}
</div>
</div>
</div>
);
}
return (
<div className='group__header-container'>
<div className='group__header'>
<div className='group__cover'>
<img src={group.get('cover_image_url')} alt='' className='parallax' />
</div>
<div className='group__tabs'>
<NavLink exact className='group__tabs__tab' activeClassName='group__tabs__tab--active' to={`/groups/${group.get('id')}`}>Posts</NavLink>
<NavLink exact className='group__tabs__tab' activeClassName='group__tabs__tab--active' to={`/groups/${group.get('id')}/members`}>Members</NavLink>
{this.getActionButton()}
{relationships.get('admin') && this.getAdminMenu()}
</div>
</div>
</div>
);
}
}

View file

@ -2,6 +2,7 @@ import React from 'react';
import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { injectIntl, defineMessages } from 'react-intl';
import Icon from 'gabsocial/components/icon';
const messages = defineMessages({
group_archived: { id: 'group.detail.archived_group', defaultMessage: 'Archived group' },

View file

@ -26,84 +26,84 @@ export default @connect(mapStateToProps)
@injectIntl
class GroupTimeline extends React.PureComponent {
static contextTypes = {
router: PropTypes.object,
};
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
columnId: PropTypes.string,
hasUnread: PropTypes.bool,
group: PropTypes.oneOfType([ImmutablePropTypes.map, PropTypes.bool]),
relationships: ImmutablePropTypes.map,
account: ImmutablePropTypes.map,
intl: PropTypes.object.isRequired,
};
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
columnId: PropTypes.string,
hasUnread: PropTypes.bool,
group: PropTypes.oneOfType([ImmutablePropTypes.map, PropTypes.bool]),
relationships: ImmutablePropTypes.map,
account: ImmutablePropTypes.map,
intl: PropTypes.object.isRequired,
};
componentDidMount () {
const { dispatch } = this.props;
const { id } = this.props.params;
componentDidMount () {
const { dispatch } = this.props;
const { id } = this.props.params;
dispatch(expandGroupTimeline(id));
dispatch(expandGroupTimeline(id));
this.disconnect = dispatch(connectGroupStream(id));
}
this.disconnect = dispatch(connectGroupStream(id));
}
componentWillUnmount () {
if (this.disconnect) {
this.disconnect();
this.disconnect = null;
}
}
componentWillUnmount () {
if (this.disconnect) {
this.disconnect();
this.disconnect = null;
}
}
handleLoadMore = maxId => {
const { id } = this.props.params;
this.props.dispatch(expandGroupTimeline(id, { maxId }));
}
handleLoadMore = maxId => {
const { id } = this.props.params;
this.props.dispatch(expandGroupTimeline(id, { maxId }));
}
render () {
const { columnId, group, relationships, account } = this.props;
const { id } = this.props.params;
render () {
const { columnId, group, relationships, account } = this.props;
const { id } = this.props.params;
if (typeof group === 'undefined' || !relationships) {
return (
<Column>
<LoadingIndicator />
</Column>
);
} else if (group === false) {
return (
<Column>
<MissingIndicator />
</Column>
);
}
if (typeof group === 'undefined' || !relationships) {
return (
<Column>
<LoadingIndicator />
</Column>
);
} else if (group === false) {
return (
<Column>
<MissingIndicator />
</Column>
);
}
return (
<div>
{relationships.get('member') && (
<div className='timeline-compose-block'>
<div className='timeline-compose-block__avatar'>
<Avatar account={account} size={46} />
</div>
<ComposeFormContainer group={group} shouldCondense autoFocus={false} />
</div>
)}
return (
<div>
{relationships.get('member') && (
<div className='timeline-compose-block'>
<div className='timeline-compose-block__avatar'>
<Avatar account={account} size={46} />
</div>
<ComposeFormContainer group={group} shouldCondense autoFocus={false} />
</div>
)}
<div className='group__feed'>
<StatusListContainer
alwaysPrepend
scrollKey={`group_timeline-${columnId}`}
timelineId={`group:${id}`}
onLoadMore={this.handleLoadMore}
group={group}
withGroupAdmin={relationships && relationships.get('admin')}
emptyMessage={<FormattedMessage id='empty_column.group' defaultMessage='There is nothing in this group yet. When members of this group make new posts, they will appear here.' />}
/>
</div>
</div>
);
}
<div className='group__feed'>
<StatusListContainer
alwaysPrepend
scrollKey={`group_timeline-${columnId}`}
timelineId={`group:${id}`}
onLoadMore={this.handleLoadMore}
group={group}
withGroupAdmin={relationships && relationships.get('admin')}
emptyMessage={<FormattedMessage id='empty_column.group' defaultMessage='There is nothing in this group yet. When members of this group make new posts, they will appear here.' />}
/>
</div>
</div>
);
}
}

View file

@ -22,7 +22,7 @@ class LandingPage extends ImmutablePureComponent {
}
render() {
const { instance, soapbox } = this.props;
const { instance } = this.props;
if (instance.isEmpty()) return null;
const siteLogo = this.getSiteLogo();

View file

@ -66,9 +66,7 @@ class ListAdder extends ImmutablePureComponent {
};
render () {
const { accountId, listIds, intl, onClose, account } = this.props;
const displayNameHtml = account ? { __html: account.get('display_name_html') } : '';
const { accountId, listIds, intl } = this.props;
return (
<div className='modal-root__modal compose-modal'>

View file

@ -47,8 +47,6 @@ class ListForm extends React.PureComponent {
render () {
const { value, disabled, intl } = this.props;
const title = intl.formatMessage(messages.title);
const save = intl.formatMessage(messages.save);
return (

View file

@ -60,8 +60,7 @@ class ListEditor extends ImmutablePureComponent {
};
render () {
const { accountIds, searchAccountIds, onClear, intl } = this.props;
const showSearch = searchAccountIds.size > 0;
const { accountIds, searchAccountIds, intl } = this.props;
return (
<div className='modal-root__modal compose-modal'>

View file

@ -50,7 +50,6 @@ class NewListForm extends React.PureComponent {
const { value, disabled, intl } = this.props;
const label = intl.formatMessage(messages.label);
const title = intl.formatMessage(messages.title);
const create = intl.formatMessage(messages.create);
return (

View file

@ -35,7 +35,7 @@ class PinnedStatuses extends ImmutablePureComponent {
}
render () {
const { intl, statusIds, hasMore, isMyAccount } = this.props;
const { statusIds, hasMore, isMyAccount } = this.props;
if (!isMyAccount) {
return (

View file

@ -7,14 +7,8 @@ import Column from '../../components/column';
import ColumnSettingsContainer from './containers/column_settings_container';
import HomeColumnHeader from '../../components/home_column_header';
import ExplanationBox from '../ui/components/explanation_box';
import {
expandCommunityTimeline,
expandPublicTimeline,
} from '../../actions/timelines';
import {
connectCommunityStream,
connectPublicStream,
} from '../../actions/streaming';
import { expandPublicTimeline } from '../../actions/timelines';
import { connectPublicStream } from '../../actions/streaming';
import { Link } from 'react-router-dom';
const messages = defineMessages({

View file

@ -1,6 +1,5 @@
import React from 'react';
import { connect } from 'react-redux';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { FormattedMessage } from 'react-intl';

View file

@ -183,7 +183,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
<div ref={this.setRef} className={classNames('detailed-status', { compact })}>
<NavLink to={`/@${status.getIn(['account', 'acct'])}`} className='detailed-status__display-name'>
<div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div>
<DisplayName account={status.get('account')} localDomain={this.props.domain} />
<DisplayName account={status.get('account')} />
</NavLink>
{status.get('group') && (

View file

@ -421,7 +421,6 @@ class Status extends ImmutablePureComponent {
render () {
let ancestors, descendants;
const { status, ancestorsIds, descendantsIds, intl, domain, me } = this.props;
const { fullscreen } = this.state;
if (status === null) {
return (

View file

@ -1,7 +1,7 @@
import React from 'react';
import { mount } from 'enzyme';
// import Column from '../column';
// import ColumnHeader from '../column_header';
import Column from '../column';
import ColumnHeader from '../column_header';
describe('<Column />', () => {
describe('<ColumnHeader /> click handler', () => {

View file

@ -4,17 +4,6 @@ import { injectIntl } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import ReactSwipeableViews from 'react-swipeable-views';
import { links, getIndex, getLink } from './tabs_bar';
import { Link } from 'react-router-dom';
import BundleContainer from '../containers/bundle_container';
import ColumnLoading from './column_loading';
import DrawerLoading from './drawer_loading';
import BundleColumnError from './bundle_column_error';
import { Compose, Notifications, HomeTimeline, CommunityTimeline, HashtagTimeline, DirectTimeline, FavouritedStatuses, ListTimeline } from '../../ui/util/async-components';
import Icon from 'gabsocial/components/icon';
export default @(component => injectIntl(component, { withRef: true }))
class ColumnsArea extends ImmutablePureComponent {
@ -26,7 +15,7 @@ class ColumnsArea extends ImmutablePureComponent {
};
render () {
const { columns, children, intl } = this.props;
const { children } = this.props;
const layout = this.props.layout || { LEFT:null, RIGHT:null };
return (

View file

@ -1,7 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
export default
class ExplanationBox extends React.PureComponent {

View file

@ -1,8 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import ProgressBar from '../../../components/progress_bar';
import { fetchFunding } from 'gabsocial/actions/patron';

View file

@ -5,7 +5,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import Button from 'gabsocial/components/button';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Icon from 'gabsocial/components/icon';
import VerificationBadge from 'gabsocial/components/verification_badge';
@ -61,7 +60,6 @@ class ProfileInfoPanel extends ImmutablePureComponent {
const badge = account.get('bot') ? (<div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div>) : null;
const content = { __html: account.get('note_emojified') };
const fields = account.get('fields');
const acct = account.get('acct');
const displayNameHtml = { __html: account.get('display_name_html') };
const memberSinceDate = intl.formatDate(account.get('created_at'), { month: 'long', year: 'numeric' });

View file

@ -1,8 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import Icon from 'gabsocial/components/icon';
import ProBadge from 'gabsocial/components/pro_badge';
import { connect } from 'react-redux';
const mapStateToProps = state => ({

View file

@ -1,7 +1,6 @@
import React from 'react';
import { connect } from 'react-redux';
import { FormattedMessage, injectIntl } from 'react-intl';
import { NavLink } from 'react-router-dom';
const mapStateToProps = state => {
return {

View file

@ -115,7 +115,7 @@ class TabsBar extends React.PureComponent {
});
render () {
const { intl: { formatMessage }, account, onOpenCompose, onOpenSidebar } = this.props;
const { account, onOpenCompose, onOpenSidebar } = this.props;
const { collapsed } = this.state;
const classes = classNames('tabs-bar', {

View file

@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import { NavLink, withRouter } from 'react-router-dom';
import { FormattedMessage, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { fetchTrends } from '../../../actions/trends';

View file

@ -1,9 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import Avatar from '../../../components/avatar';
import ImmutablePureComponent from 'react-immutable-pure-component';
import IconButton from 'gabsocial/components/icon_button';
@ -31,7 +29,7 @@ class UnauthorizedModal extends ImmutablePureComponent {
};
render () {
const { intl, onClose, account, siteTitle } = this.props;
const { intl, siteTitle } = this.props;
return (
<div className='modal-root__modal compose-modal unauthorized-modal'>

View file

@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import { NavLink, withRouter } from 'react-router-dom';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { fetchSuggestions, dismissSuggestion } from '../../../actions/suggestions';

View file

@ -5,7 +5,7 @@ import React from 'react';
import { HotKeys } from 'react-hotkeys';
import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { Switch, Redirect, withRouter } from 'react-router-dom';
import { Switch, withRouter } from 'react-router-dom';
import PropTypes from 'prop-types';
import NotificationsContainer from './containers/notifications_container';
import LoadingBarContainer from './containers/loading_bar_container';
@ -18,24 +18,24 @@ import { initializeNotifications, expandNotifications } from '../../actions/noti
import { fetchFilters } from '../../actions/filters';
import { clearHeight } from '../../actions/height_cache';
import { openModal } from '../../actions/modal';
import { WrappedSwitch, WrappedRoute } from './util/react_router_helpers';
import { WrappedRoute } from './util/react_router_helpers';
import UploadArea from './components/upload_area';
import TabsBar from './components/tabs_bar';
// import TrendsPanel from './components/trends_panel';
import WhoToFollowPanel from './components/who_to_follow_panel';
import LinkFooter from './components/link_footer';
import ProfilePage from 'gabsocial/pages/profile_page';
import GroupsPage from 'gabsocial/pages/groups_page';
import GroupPage from 'gabsocial/pages/group_page';
// import GroupsPage from 'gabsocial/pages/groups_page';
// import GroupPage from 'gabsocial/pages/group_page';
// import GroupSidebarPanel from '../groups/sidebar_panel';
import SearchPage from 'gabsocial/pages/search_page';
import HomePage from 'gabsocial/pages/home_page';
import GroupSidebarPanel from '../groups/sidebar_panel';
import SidebarMenu from '../../components/sidebar_menu';
import { connectUserStream } from '../../actions/streaming';
import {
Status,
GettingStarted,
// GettingStarted,
CommunityTimeline,
PublicTimeline,
AccountTimeline,
@ -44,7 +44,7 @@ import {
Followers,
Following,
Reblogs,
Favourites,
// Favourites,
DirectTimeline,
HashtagTimeline,
Notifications,
@ -56,25 +56,22 @@ import {
Mutes,
PinnedStatuses,
Search,
Explore,
Groups,
GroupTimeline,
// Explore,
// Groups,
// GroupTimeline,
ListTimeline,
Lists,
GroupMembers,
GroupRemovedAccounts,
GroupCreate,
GroupEdit,
// GroupMembers,
// GroupRemovedAccounts,
// GroupCreate,
// GroupEdit,
LoginPage,
} from './util/async-components';
import { meUsername } from '../../initial_state';
import { previewState as previewMediaState } from './components/media_modal';
import { previewState as previewVideoState } from './components/video_modal';
// Dummy import, to make sure that <Status /> ends up in the application bundle.
// Without this it ends up in ~8 very commonly used bundles.
import '../../components/status';
import { fetchGroups } from '../../actions/groups';
const messages = defineMessages({
beforeUnload: { id: 'ui.beforeunload', defaultMessage: 'Your draft will be lost if you leave.' },
@ -184,8 +181,7 @@ class SwitchingColumnsArea extends React.PureComponent {
}
render () {
const { children, account } = this.props;
const { mobile } = this.state;
const { children } = this.props;
return (
<Switch>
@ -535,7 +531,7 @@ class UI extends React.PureComponent {
const { draggingOver } = this.state;
const { intl, children, isComposing, location, dropdownMenuIsOpen, me } = this.props;
if (me == null || !streamingUrl) return null;
if (me === null || !streamingUrl) return null;
const handlers = me ? {
help: this.handleHotkeyToggleHelp,

View file

@ -73,7 +73,7 @@ class WrappedRoute extends React.Component {
render () {
const { component: Component, content, publicRoute, me, ...rest } = this.props;
if (!publicRoute && me == false) {
if (!publicRoute && me === false) {
const actualUrl = encodeURIComponent(this.props.computedMatch.url);
return <Redirect to={`/auth/sign_in?redirect_uri=${actualUrl}`} />;
// return <Route path={this.props.path} component={() => {

View file

@ -1,6 +1,5 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import ImmutablePureComponent from 'react-immutable-pure-component';
import WhoToFollowPanel from '../features/ui/components/who_to_follow_panel';
import TrendsPanel from '../features/ui/components/trends_panel';
@ -10,7 +9,7 @@ import UserPanel from '../features/ui/components/user_panel';
import FundingPanel from '../features/ui/components/funding_panel';
import ComposeFormContainer from '../features/compose/containers/compose_form_container';
import Avatar from '../components/avatar';
import GroupSidebarPanel from '../features/groups/sidebar_panel';
// import GroupSidebarPanel from '../features/groups/sidebar_panel';
const mapStateToProps = state => {
const me = state.get('me');

View file

@ -2,22 +2,17 @@ import React from 'react';
import { connect } from 'react-redux';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import { fetchAccount, fetchAccountByUsername } from '../actions/accounts';
import { List as ImmutableList } from 'immutable';
import ImmutablePureComponent from 'react-immutable-pure-component';
import HeaderContainer from '../features/account_timeline/containers/header_container';
import { NavLink } from 'react-router-dom';
import WhoToFollowPanel from '../features/ui/components/who_to_follow_panel';
// import TrendsPanel from '../features/ui/components/trends_panel';
import LinkFooter from '../features/ui/components/link_footer';
import SignUpPanel from '../features/ui/components/sign_up_panel';
import ProfileInfoPanel from '../features/ui/components/profile_info_panel';
const emptyList = ImmutableList();
const mapStateToProps = (state, { params: { username }, withReplies = false }) => {
const accounts = state.getIn(['accounts']);
const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() == username.toLowerCase());
const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() === username.toLowerCase());
let accountId = -1;
let account = null;
@ -25,7 +20,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
if (accountFetchError) {
accountId = null;
} else {
account = accounts.find(acct => username.toLowerCase() == acct.getIn(['acct'], '').toLowerCase());
account = accounts.find(acct => username.toLowerCase() === acct.getIn(['acct'], '').toLowerCase());
accountId = account ? account.getIn(['id'], null) : -1;
accountUsername = account ? account.getIn(['acct'], '') : '';
}

View file

@ -4,7 +4,7 @@ import {
AUTH_APP_AUTHORIZED,
AUTH_LOGGED_OUT,
} from '../actions/auth';
import { Map as ImmutableMap, fromJS } from 'immutable';
import { Map as ImmutableMap } from 'immutable';
const initialState = ImmutableMap({
app: ImmutableMap(JSON.parse(localStorage.getItem('soapbox:auth:app'))),

View file

@ -1,6 +1,6 @@
import { ME_FETCH_SUCCESS, ME_FETCH_FAIL, ME_FETCH_SKIP } from '../actions/me';
import { AUTH_LOGGED_OUT } from '../actions/auth';
import { Map as ImmutableMap, fromJS } from 'immutable';
import { fromJS } from 'immutable';
const initialState = null;

View file

@ -1,4 +1,4 @@
import React, { Fragment } from 'react';
import React from 'react';
import { FormattedNumber } from 'react-intl';
export const shortNumberFormat = number => {

View file

@ -102,14 +102,16 @@ delegate(document, '.payform', 'submit', (e) => {
const csrf_token = document.querySelector('meta[name=\'csrf-token\']').content;
const price = Math.floor(document.getElementById('price').value.replace(/[^0-9.]/, '') * 100);
// eslint-disable-next-line no-undef
const stripe = Stripe(stripe_pk);
const req = new XMLHttpRequest();
function checkout () {
function checkout() {
stripe.redirectToCheckout({
sessionId: this.responseText,
}).then(function (result) {
console.log(result.error.message);
}).catch(e => {
console.error(e);
console.error('Could not connect to Stripe checkout');
});
}

View file

@ -25,7 +25,7 @@ window.addEventListener('message', e => {
function main ( ) {
const IntlMessageFormat = require('intl-messageformat').default;
import('intl-pluralrules');
import('intl-pluralrules'); // eslint-disable-line
const { timeAgoString } = require('../gabsocial/components/relative_timestamp');
const { delegate } = require('rails-ujs');
const emojify = require('../gabsocial/features/emoji/emoji').default;
@ -35,7 +35,7 @@ function main ( ) {
// const React = require('react');
const ReactDOM = require('react-dom');
const Rellax = require('rellax');
const createHistory = require('history').createBrowserHistory;
const createHistory = require('history').createBrowserHistory; // eslint-disable-line
const scrollToDetailedStatus = () => {
const history = createHistory();

View file

@ -128,7 +128,7 @@
"websocket.js": "^0.1.12"
},
"devDependencies": {
"babel-eslint": "^10.0.1",
"babel-eslint": "^10.1.0",
"babel-jest": "^24.8.0",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1",

View file

@ -1,10 +1,9 @@
// Note: You must restart bin/webpack-dev-server for changes to take effect
const { resolve, join } = require('path');
const { resolve } = require('path');
const merge = require('webpack-merge');
const sharedConfig = require('./shared');
const { settings, output } = require('./configuration');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const watchOptions = {};

View file

@ -1,6 +1,5 @@
// Note: You must restart bin/webpack-dev-server for changes to take effect
const path = require('path');
const { URL } = require('url');
const merge = require('webpack-merge');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
@ -10,6 +9,7 @@ const CompressionPlugin = require('compression-webpack-plugin');
const { output } = require('./configuration');
const sharedConfig = require('./shared');
// eslint-disable-next-line no-unused-vars
let attachmentHost;
if (process.env.S3_ENABLED === 'true') {

159
yarn.lock
View file

@ -2,12 +2,12 @@
# yarn lockfile v1
"@babel/code-frame@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8"
integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==
dependencies:
"@babel/highlight" "^7.0.0"
"@babel/highlight" "^7.8.3"
"@babel/core@^7.1.0", "@babel/core@^7.3.4":
version "7.3.4"
@ -51,6 +51,16 @@
source-map "^0.5.0"
trim-right "^1.0.1"
"@babel/generator@^7.9.5":
version "7.9.5"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.5.tgz#27f0917741acc41e6eaaced6d68f96c3fa9afaf9"
integrity sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==
dependencies:
"@babel/types" "^7.9.5"
jsesc "^2.5.1"
lodash "^4.17.13"
source-map "^0.5.0"
"@babel/helper-annotate-as-pure@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32"
@ -121,6 +131,15 @@
"@babel/template" "^7.1.0"
"@babel/types" "^7.0.0"
"@babel/helper-function-name@^7.9.5":
version "7.9.5"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c"
integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==
dependencies:
"@babel/helper-get-function-arity" "^7.8.3"
"@babel/template" "^7.8.3"
"@babel/types" "^7.9.5"
"@babel/helper-get-function-arity@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3"
@ -128,6 +147,13 @@
dependencies:
"@babel/types" "^7.0.0"
"@babel/helper-get-function-arity@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5"
integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==
dependencies:
"@babel/types" "^7.8.3"
"@babel/helper-hoist-variables@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz#46adc4c5e758645ae7a45deb92bab0918c23bb88"
@ -226,6 +252,18 @@
dependencies:
"@babel/types" "^7.0.0"
"@babel/helper-split-export-declaration@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9"
integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==
dependencies:
"@babel/types" "^7.8.3"
"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5":
version "7.9.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80"
integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==
"@babel/helper-wrap-function@^7.1.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa"
@ -245,13 +283,13 @@
"@babel/traverse" "^7.1.5"
"@babel/types" "^7.2.0"
"@babel/highlight@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4"
integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==
"@babel/highlight@^7.8.3":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079"
integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==
dependencies:
"@babel/helper-validator-identifier" "^7.9.0"
chalk "^2.0.0"
esutils "^2.0.2"
js-tokens "^4.0.0"
"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.2.3":
@ -264,6 +302,11 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.4.tgz#a43357e4bbf4b92a437fb9e465c192848287f27c"
integrity sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==
"@babel/parser@^7.7.0", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0":
version "7.9.4"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8"
integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==
"@babel/plugin-proposal-async-generator-functions@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e"
@ -748,6 +791,15 @@
"@babel/parser" "^7.2.2"
"@babel/types" "^7.2.2"
"@babel/template@^7.8.3":
version "7.8.6"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b"
integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==
dependencies:
"@babel/code-frame" "^7.8.3"
"@babel/parser" "^7.8.6"
"@babel/types" "^7.8.6"
"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.2.3":
version "7.2.3"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8"
@ -778,6 +830,21 @@
globals "^11.1.0"
lodash "^4.17.11"
"@babel/traverse@^7.7.0":
version "7.9.5"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.5.tgz#6e7c56b44e2ac7011a948c21e283ddd9d9db97a2"
integrity sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==
dependencies:
"@babel/code-frame" "^7.8.3"
"@babel/generator" "^7.9.5"
"@babel/helper-function-name" "^7.9.5"
"@babel/helper-split-export-declaration" "^7.8.3"
"@babel/parser" "^7.9.0"
"@babel/types" "^7.9.5"
debug "^4.1.0"
globals "^11.1.0"
lodash "^4.17.13"
"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.2.tgz#44e10fc24e33af524488b716cdaee5360ea8ed1e"
@ -796,6 +863,15 @@
lodash "^4.17.11"
to-fast-properties "^2.0.0"
"@babel/types@^7.7.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.5":
version "7.9.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.5.tgz#89231f82915a8a566a703b3b20133f73da6b9444"
integrity sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==
dependencies:
"@babel/helper-validator-identifier" "^7.9.5"
lodash "^4.17.13"
to-fast-properties "^2.0.0"
"@clusterws/cws@^0.16.0":
version "0.16.0"
resolved "https://registry.yarnpkg.com/@clusterws/cws/-/cws-0.16.0.tgz#f6116cbf3a8b7ad0657916616ce5f8248746b797"
@ -1685,17 +1761,17 @@ axobject-query@^2.0.2:
dependencies:
ast-types-flow "0.0.7"
babel-eslint@^10.0.1:
version "10.0.1"
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed"
integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==
babel-eslint@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232"
integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==
dependencies:
"@babel/code-frame" "^7.0.0"
"@babel/parser" "^7.0.0"
"@babel/traverse" "^7.0.0"
"@babel/types" "^7.0.0"
eslint-scope "3.7.1"
"@babel/parser" "^7.7.0"
"@babel/traverse" "^7.7.0"
"@babel/types" "^7.7.0"
eslint-visitor-keys "^1.0.0"
resolve "^1.12.0"
babel-jest@^24.8.0:
version "24.8.0"
@ -3768,14 +3844,6 @@ eslint-plugin-react@~7.17.0:
prop-types "^15.7.2"
resolve "^1.13.1"
eslint-scope@3.7.1:
version "3.7.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=
dependencies:
esrecurse "^4.1.0"
estraverse "^4.1.1"
eslint-scope@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848"
@ -3799,12 +3867,7 @@ eslint-utils@^1.4.2:
dependencies:
eslint-visitor-keys "^1.0.0"
eslint-visitor-keys@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==
eslint-visitor-keys@^1.1.0:
eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
@ -3937,11 +4000,16 @@ estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=
esutils@^2.0.0, esutils@^2.0.2:
esutils@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
@ -4610,7 +4678,12 @@ global-prefix@^1.0.1:
is-windows "^1.0.1"
which "^1.2.14"
globals@^11.1.0, globals@^11.7.0:
globals@^11.1.0:
version "11.12.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
globals@^11.7.0:
version "11.9.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249"
integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==
@ -6407,7 +6480,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@^4.0.0, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.3.0, lodash@~4.17.12:
lodash@^4.0.0, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.3.0, lodash@~4.17.12:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@ -6760,11 +6833,16 @@ ms@2.0.0:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
ms@2.1.1, ms@^2.1.1:
ms@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
ms@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
multicast-dns-service-types@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901"
@ -9030,7 +9108,14 @@ resolve@^1.10.0:
dependencies:
path-parse "^1.0.6"
resolve@^1.12.0, resolve@^1.13.1:
resolve@^1.12.0:
version "1.15.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==
dependencies:
path-parse "^1.0.6"
resolve@^1.13.1:
version "1.13.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.13.1.tgz#be0aa4c06acd53083505abb35f4d66932ab35d16"
integrity sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==