[build] upgrade eslint to 9.37.0 (#88)
Co-authored-by: tobi <tobi.smethurst@protonmail.com> Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/88 Co-authored-by: Zoë Bijl <moiety@noreply.codeberg.org> Co-committed-by: Zoë Bijl <moiety@noreply.codeberg.org>
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import classNames from "classnames";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
|
||||
import { Avatar } from 'flavours/glitch/components/avatar';
|
||||
import { DisplayName } from 'flavours/glitch/components/display_name';
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp';
|
||||
import StatusContent from 'flavours/glitch/components/status_content';
|
||||
import { Avatar } from "flavours/glitch/components/avatar";
|
||||
import { DisplayName } from "flavours/glitch/components/display_name";
|
||||
import { IconButton } from "flavours/glitch/components/icon_button";
|
||||
import { RelativeTimestamp } from "flavours/glitch/components/relative_timestamp";
|
||||
import StatusContent from "flavours/glitch/components/status_content";
|
||||
|
||||
export default class ActionsModal extends ImmutablePureComponent {
|
||||
|
||||
@@ -32,7 +32,7 @@ export default class ActionsModal extends ImmutablePureComponent {
|
||||
return <li key={`sep-${i}`} className='dropdown-menu__separator' />;
|
||||
}
|
||||
|
||||
const { icon = null, text, meta = null, active = false, href = '#' } = action;
|
||||
const { icon = null, text, meta = null, active = false, href = "#" } = action;
|
||||
let contents = this.props.renderItemContents && this.props.renderItemContents(action, i);
|
||||
|
||||
if (!contents) {
|
||||
@@ -40,7 +40,7 @@ export default class ActionsModal extends ImmutablePureComponent {
|
||||
<>
|
||||
{icon && <IconButton title={text} icon={icon} role='presentation' tabIndex={-1} inverted />}
|
||||
<div>
|
||||
<div className={classNames({ 'actions-modal__item-label': !!meta })}>{text}</div>
|
||||
<div className={classNames({ "actions-modal__item-label": !!meta })}>{text}</div>
|
||||
<div>{meta}</div>
|
||||
</div>
|
||||
</>
|
||||
@@ -49,7 +49,7 @@ export default class ActionsModal extends ImmutablePureComponent {
|
||||
|
||||
return (
|
||||
<li key={`${text}-${i}`}>
|
||||
<a href={href} target='_blank' rel='noopener noreferrer' onClick={this.props.onClick} data-index={i} className={classNames('link', { active })}>
|
||||
<a href={href} target='_blank' rel='noopener noreferrer' onClick={this.props.onClick} data-index={i} className={classNames("link", { active })}>
|
||||
{contents}
|
||||
</a>
|
||||
</li>
|
||||
@@ -61,17 +61,17 @@ export default class ActionsModal extends ImmutablePureComponent {
|
||||
<div className='status light'>
|
||||
<div className='boost-modal__status-header'>
|
||||
<div className='boost-modal__status-time'>
|
||||
<a href={this.props.status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
||||
<RelativeTimestamp timestamp={this.props.status.get('created_at')} />
|
||||
<a href={this.props.status.get("url")} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
||||
<RelativeTimestamp timestamp={this.props.status.get("created_at")} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<a href={this.props.status.getIn(['account', 'url'])} className='status__display-name' rel='noopener noreferrer'>
|
||||
<a href={this.props.status.getIn(["account", "url"])} className='status__display-name' rel='noopener noreferrer'>
|
||||
<div className='status__avatar'>
|
||||
<Avatar account={this.props.status.get('account')} size={48} />
|
||||
<Avatar account={this.props.status.get("account")} size={48} />
|
||||
</div>
|
||||
|
||||
<DisplayName account={this.props.status.get('account')} />
|
||||
<DisplayName account={this.props.status.get("account")} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -83,7 +83,7 @@ export default class ActionsModal extends ImmutablePureComponent {
|
||||
<div className='modal-root__modal actions-modal'>
|
||||
{status}
|
||||
|
||||
<ul className={classNames({ 'with-status': !!status })}>
|
||||
<ul className={classNames({ "with-status": !!status })}>
|
||||
{this.props.actions.map(this.renderAction)}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import Audio from 'flavours/glitch/features/audio';
|
||||
import Footer from 'flavours/glitch/features/picture_in_picture/components/footer';
|
||||
import Audio from "flavours/glitch/features/audio";
|
||||
import Footer from "flavours/glitch/features/picture_in_picture/components/footer";
|
||||
|
||||
const mapStateToProps = (state, { statusId }) => ({
|
||||
status: state.getIn(['statuses', statusId]),
|
||||
accountStaticAvatar: state.getIn(['accounts', state.getIn(['statuses', statusId, 'account']), 'avatar_static']),
|
||||
status: state.getIn(["statuses", statusId]),
|
||||
accountStaticAvatar: state.getIn(["accounts", state.getIn(["statuses", statusId, "account"]), "avatar_static"]),
|
||||
});
|
||||
|
||||
class AudioModal extends ImmutablePureComponent {
|
||||
@@ -33,28 +33,28 @@ class AudioModal extends ImmutablePureComponent {
|
||||
render () {
|
||||
const { media, status, accountStaticAvatar, onClose } = this.props;
|
||||
const options = this.props.options || {};
|
||||
const language = status.getIn(['translation', 'language']) || status.get('language');
|
||||
const description = media.getIn(['translation', 'description']) || media.get('description');
|
||||
const language = status.getIn(["translation", "language"]) || status.get("language");
|
||||
const description = media.getIn(["translation", "description"]) || media.get("description");
|
||||
|
||||
return (
|
||||
<div className='modal-root__modal audio-modal'>
|
||||
<div className='audio-modal__container'>
|
||||
<Audio
|
||||
src={media.get('url')}
|
||||
src={media.get("url")}
|
||||
alt={description}
|
||||
lang={language}
|
||||
duration={media.getIn(['meta', 'original', 'duration'], 0)}
|
||||
duration={media.getIn(["meta", "original", "duration"], 0)}
|
||||
height={150}
|
||||
poster={media.get('preview_url') || accountStaticAvatar}
|
||||
backgroundColor={media.getIn(['meta', 'colors', 'background'])}
|
||||
foregroundColor={media.getIn(['meta', 'colors', 'foreground'])}
|
||||
accentColor={media.getIn(['meta', 'colors', 'accent'])}
|
||||
poster={media.get("preview_url") || accountStaticAvatar}
|
||||
backgroundColor={media.getIn(["meta", "colors", "background"])}
|
||||
foregroundColor={media.getIn(["meta", "colors", "foreground"])}
|
||||
accentColor={media.getIn(["meta", "colors", "accent"])}
|
||||
autoPlay={options.autoPlay}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='media-modal__overlay'>
|
||||
{status && <Footer statusId={status.get('id')} withOpenButton onClose={onClose} />}
|
||||
{status && <Footer statusId={status.get("id")} withOpenButton onClose={onClose} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { injectIntl, FormattedMessage } from "react-intl";
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { blockAccount } from '../../../actions/accounts';
|
||||
import { closeModal } from '../../../actions/modal';
|
||||
import { initReport } from '../../../actions/reports';
|
||||
import Button from '../../../components/button';
|
||||
import { makeGetAccount } from '../../../selectors';
|
||||
import { blockAccount } from "../../../actions/accounts";
|
||||
import { closeModal } from "../../../actions/modal";
|
||||
import { initReport } from "../../../actions/reports";
|
||||
import Button from "../../../components/button";
|
||||
import { makeGetAccount } from "../../../selectors";
|
||||
|
||||
|
||||
const makeMapStateToProps = () => {
|
||||
const getAccount = makeGetAccount();
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
account: getAccount(state, state.getIn(['blocks', 'new', 'account_id'])),
|
||||
account: getAccount(state, state.getIn(["blocks", "new", "account_id"])),
|
||||
});
|
||||
|
||||
return mapStateToProps;
|
||||
@@ -25,11 +25,11 @@ const makeMapStateToProps = () => {
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
onConfirm(account) {
|
||||
dispatch(blockAccount(account.get('id')));
|
||||
dispatch(blockAccount(account.get("id")));
|
||||
},
|
||||
|
||||
onBlockAndReport(account) {
|
||||
dispatch(blockAccount(account.get('id')));
|
||||
dispatch(blockAccount(account.get("id")));
|
||||
dispatch(initReport(account));
|
||||
},
|
||||
|
||||
@@ -84,7 +84,7 @@ class BlockModal extends PureComponent {
|
||||
<FormattedMessage
|
||||
id='confirmations.block.message'
|
||||
defaultMessage='Are you sure you want to block {name}?'
|
||||
values={{ name: <strong>@{account.get('acct')}</strong> }}
|
||||
values={{ name: <strong>@{account.get("acct")}</strong> }}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from "react-intl";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import classNames from "classnames";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { changeBoostPrivacy } from 'flavours/glitch/actions/boosts';
|
||||
import AttachmentList from 'flavours/glitch/components/attachment_list';
|
||||
import { Avatar } from 'flavours/glitch/components/avatar';
|
||||
import Button from 'flavours/glitch/components/button';
|
||||
import { DisplayName } from 'flavours/glitch/components/display_name';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp';
|
||||
import StatusContent from 'flavours/glitch/components/status_content';
|
||||
import VisibilityIcon from 'flavours/glitch/components/status_visibility_icon';
|
||||
import PrivacyDropdown from 'flavours/glitch/features/compose/components/privacy_dropdown';
|
||||
import { changeBoostPrivacy } from "flavours/glitch/actions/boosts";
|
||||
import AttachmentList from "flavours/glitch/components/attachment_list";
|
||||
import { Avatar } from "flavours/glitch/components/avatar";
|
||||
import Button from "flavours/glitch/components/button";
|
||||
import { DisplayName } from "flavours/glitch/components/display_name";
|
||||
import { Icon } from "flavours/glitch/components/icon";
|
||||
import { RelativeTimestamp } from "flavours/glitch/components/relative_timestamp";
|
||||
import StatusContent from "flavours/glitch/components/status_content";
|
||||
import VisibilityIcon from "flavours/glitch/components/status_visibility_icon";
|
||||
import PrivacyDropdown from "flavours/glitch/features/compose/components/privacy_dropdown";
|
||||
|
||||
const messages = defineMessages({
|
||||
cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
|
||||
reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
|
||||
cancel_reblog: { id: "status.cancel_reblog_private", defaultMessage: "Unboost" },
|
||||
reblog: { id: "status.reblog", defaultMessage: "Boost" },
|
||||
});
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
privacy: state.getIn(['boosts', 'new', 'privacy']),
|
||||
privacy: state.getIn(["boosts", "new", "privacy"]),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -65,12 +65,12 @@ class BoostModal extends ImmutablePureComponent {
|
||||
if (e.button === 0) {
|
||||
e.preventDefault();
|
||||
this.props.onClose();
|
||||
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
|
||||
this.context.router.history.push(`/@${this.props.status.getIn(["account", "acct"])}`);
|
||||
}
|
||||
};
|
||||
|
||||
_findContainer = () => {
|
||||
return document.getElementsByClassName('modal-root__container')[0];
|
||||
return document.getElementsByClassName("modal-root__container")[0];
|
||||
};
|
||||
|
||||
setRef = (c) => {
|
||||
@@ -79,34 +79,34 @@ class BoostModal extends ImmutablePureComponent {
|
||||
|
||||
render () {
|
||||
const { status, missingMediaDescription, privacy, intl } = this.props;
|
||||
const buttonText = status.get('reblogged') ? messages.cancel_reblog : messages.reblog;
|
||||
const buttonText = status.get("reblogged") ? messages.cancel_reblog : messages.reblog;
|
||||
|
||||
return (
|
||||
<div className='modal-root__modal boost-modal'>
|
||||
<div className='boost-modal__container'>
|
||||
<div className={classNames('status', `status-${status.get('visibility')}`, 'light')}>
|
||||
<div className={classNames("status", `status-${status.get("visibility")}`, "light")}>
|
||||
<div className='boost-modal__status-header'>
|
||||
<div className='boost-modal__status-time'>
|
||||
<a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
||||
<VisibilityIcon visibility={status.get('visibility')} />
|
||||
<RelativeTimestamp timestamp={status.get('created_at')} /></a>
|
||||
<a href={status.get("url")} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
||||
<VisibilityIcon visibility={status.get("visibility")} />
|
||||
<RelativeTimestamp timestamp={status.get("created_at")} /></a>
|
||||
</div>
|
||||
|
||||
<a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name'>
|
||||
<a onClick={this.handleAccountClick} href={status.getIn(["account", "url"])} className='status__display-name'>
|
||||
<div className='status__avatar'>
|
||||
<Avatar account={status.get('account')} size={48} />
|
||||
<Avatar account={status.get("account")} size={48} />
|
||||
</div>
|
||||
|
||||
<DisplayName account={status.get('account')} />
|
||||
<DisplayName account={status.get("account")} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<StatusContent status={status} />
|
||||
|
||||
{status.get('media_attachments').size > 0 && (
|
||||
{status.get("media_attachments").size > 0 && (
|
||||
<AttachmentList
|
||||
compact
|
||||
media={status.get('media_attachments')}
|
||||
media={status.get("media_attachments")}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -121,7 +121,7 @@ class BoostModal extends ImmutablePureComponent {
|
||||
}
|
||||
</div>
|
||||
|
||||
{status.get('visibility') !== 'private' && !status.get('reblogged') && (
|
||||
{status.get("visibility") !== "private" && !status.get("reblogged") && (
|
||||
<PrivacyDropdown
|
||||
noDirect
|
||||
value={privacy}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { Component } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { Component } from "react";
|
||||
|
||||
const emptyComponent = () => null;
|
||||
const noop = () => { };
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { injectIntl, FormattedMessage } from "react-intl";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { Link } from 'react-router-dom';
|
||||
import classNames from "classnames";
|
||||
import { Helmet } from "react-helmet";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import Button from 'flavours/glitch/components/button';
|
||||
import Column from 'flavours/glitch/components/column';
|
||||
import { autoPlayGif } from 'flavours/glitch/initial_state';
|
||||
import Button from "flavours/glitch/components/button";
|
||||
import Column from "flavours/glitch/components/column";
|
||||
import { autoPlayGif } from "flavours/glitch/initial_state";
|
||||
|
||||
class GIF extends PureComponent {
|
||||
|
||||
@@ -81,7 +81,9 @@ class CopyButton extends PureComponent {
|
||||
};
|
||||
|
||||
componentWillUnmount () {
|
||||
if (this.timeout) clearTimeout(this.timeout);
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
@@ -89,7 +91,7 @@ class CopyButton extends PureComponent {
|
||||
const { copied } = this.state;
|
||||
|
||||
return (
|
||||
<Button onClick={this.handleClick} className={copied ? 'copied' : 'copyable'}>{copied ? <FormattedMessage id='copypaste.copied' defaultMessage='Copied' /> : children}</Button>
|
||||
<Button onClick={this.handleClick} className={copied ? "copied" : "copyable"}>{copied ? <FormattedMessage id='copypaste.copied' defaultMessage='Copied' /> : children}</Button>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -98,7 +100,7 @@ class CopyButton extends PureComponent {
|
||||
class BundleColumnError extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
errorType: PropTypes.oneOf(['routing', 'network', 'error']),
|
||||
errorType: PropTypes.oneOf(["routing", "network", "error"]),
|
||||
onRetry: PropTypes.func,
|
||||
intl: PropTypes.object.isRequired,
|
||||
multiColumn: PropTypes.bool,
|
||||
@@ -106,7 +108,7 @@ class BundleColumnError extends PureComponent {
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
errorType: 'routing',
|
||||
errorType: "routing",
|
||||
};
|
||||
|
||||
handleRetry = () => {
|
||||
@@ -123,18 +125,18 @@ class BundleColumnError extends PureComponent {
|
||||
let title, body;
|
||||
|
||||
switch(errorType) {
|
||||
case 'routing':
|
||||
title = <FormattedMessage id='bundle_column_error.routing.title' defaultMessage='404' />;
|
||||
body = <FormattedMessage id='bundle_column_error.routing.body' defaultMessage='The requested page could not be found. Are you sure the URL in the address bar is correct?' />;
|
||||
break;
|
||||
case 'network':
|
||||
title = <FormattedMessage id='bundle_column_error.network.title' defaultMessage='Network error' />;
|
||||
body = <FormattedMessage id='bundle_column_error.network.body' defaultMessage='There was an error when trying to load this page. This could be due to a temporary problem with your internet connection or this server.' />;
|
||||
break;
|
||||
case 'error':
|
||||
title = <FormattedMessage id='bundle_column_error.error.title' defaultMessage='Oh, no!' />;
|
||||
body = <FormattedMessage id='bundle_column_error.error.body' defaultMessage='The requested page could not be rendered. It could be due to a bug in our code, or a browser compatibility issue.' />;
|
||||
break;
|
||||
case "routing":
|
||||
title = <FormattedMessage id='bundle_column_error.routing.title' defaultMessage='404' />;
|
||||
body = <FormattedMessage id='bundle_column_error.routing.body' defaultMessage='The requested page could not be found. Are you sure the URL in the address bar is correct?' />;
|
||||
break;
|
||||
case "network":
|
||||
title = <FormattedMessage id='bundle_column_error.network.title' defaultMessage='Network error' />;
|
||||
body = <FormattedMessage id='bundle_column_error.network.body' defaultMessage='There was an error when trying to load this page. This could be due to a temporary problem with your internet connection or this server.' />;
|
||||
break;
|
||||
case "error":
|
||||
title = <FormattedMessage id='bundle_column_error.error.title' defaultMessage='Oh, no!' />;
|
||||
body = <FormattedMessage id='bundle_column_error.error.body' defaultMessage='The requested page could not be rendered. It could be due to a bug in our code, or a browser compatibility issue.' />;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -147,9 +149,9 @@ class BundleColumnError extends PureComponent {
|
||||
<p>{body}</p>
|
||||
|
||||
<div className='error-column__message__actions'>
|
||||
{errorType === 'network' && <Button onClick={this.handleRetry}><FormattedMessage id='bundle_column_error.retry' defaultMessage='Try again' /></Button>}
|
||||
{errorType === 'error' && <CopyButton value={stacktrace}><FormattedMessage id='bundle_column_error.copy_stacktrace' defaultMessage='Copy error report' /></CopyButton>}
|
||||
<Link to='/' className={classNames('button', { 'button-tertiary': errorType !== 'routing' })}><FormattedMessage id='bundle_column_error.return' defaultMessage='Go back home' /></Link>
|
||||
{errorType === "network" && <Button onClick={this.handleRetry}><FormattedMessage id='bundle_column_error.retry' defaultMessage='Try again' /></Button>}
|
||||
{errorType === "error" && <CopyButton value={stacktrace}><FormattedMessage id='bundle_column_error.copy_stacktrace' defaultMessage='Copy error report' /></CopyButton>}
|
||||
<Link to='/' className={classNames("button", { "button-tertiary": errorType !== "routing" })}><FormattedMessage id='bundle_column_error.return' defaultMessage='Go back home' /></Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { Component } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { Component } from "react";
|
||||
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { defineMessages, injectIntl } from "react-intl";
|
||||
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import { IconButton } from "flavours/glitch/components/icon_button";
|
||||
|
||||
const messages = defineMessages({
|
||||
error: { id: 'bundle_modal_error.message', defaultMessage: 'Something went wrong while loading this component.' },
|
||||
retry: { id: 'bundle_modal_error.retry', defaultMessage: 'Try again' },
|
||||
close: { id: 'bundle_modal_error.close', defaultMessage: 'Close' },
|
||||
error: { id: "bundle_modal_error.message", defaultMessage: "Something went wrong while loading this component." },
|
||||
retry: { id: "bundle_modal_error.retry", defaultMessage: "Try again" },
|
||||
close: { id: "bundle_modal_error.close", defaultMessage: "Close" },
|
||||
});
|
||||
|
||||
class BundleModalError extends Component {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { debounce } from 'lodash';
|
||||
import { debounce } from "lodash";
|
||||
|
||||
import { isMobile } from 'flavours/glitch/is_mobile';
|
||||
import { scrollTop } from 'flavours/glitch/scroll';
|
||||
import { isMobile } from "flavours/glitch/is_mobile";
|
||||
import { scrollTop } from "flavours/glitch/scroll";
|
||||
|
||||
import ColumnHeader from './column_header';
|
||||
import ColumnHeader from "./column_header";
|
||||
|
||||
export default class Column extends PureComponent {
|
||||
|
||||
@@ -21,7 +21,7 @@ export default class Column extends PureComponent {
|
||||
};
|
||||
|
||||
handleHeaderClick = () => {
|
||||
const scrollable = this.props.bindToDocument ? document.scrollingElement : this.node.querySelector('.scrollable');
|
||||
const scrollable = this.props.bindToDocument ? document.scrollingElement : this.node.querySelector(".scrollable");
|
||||
|
||||
if (!scrollable) {
|
||||
return;
|
||||
@@ -31,7 +31,7 @@ export default class Column extends PureComponent {
|
||||
};
|
||||
|
||||
scrollTop () {
|
||||
const scrollable = this.props.bindToDocument ? document.scrollingElement : this.node.querySelector('.scrollable');
|
||||
const scrollable = this.props.bindToDocument ? document.scrollingElement : this.node.querySelector(".scrollable");
|
||||
|
||||
if (!scrollable) {
|
||||
return;
|
||||
@@ -42,7 +42,7 @@ export default class Column extends PureComponent {
|
||||
|
||||
|
||||
handleScroll = debounce(() => {
|
||||
if (typeof this._interruptScrollAnimation !== 'undefined') {
|
||||
if (typeof this._interruptScrollAnimation !== "undefined") {
|
||||
this._interruptScrollAnimation();
|
||||
}
|
||||
}, 200);
|
||||
@@ -56,7 +56,7 @@ export default class Column extends PureComponent {
|
||||
|
||||
const showHeading = heading && (!hideHeadingOnMobile || (hideHeadingOnMobile && !isMobile(window.innerWidth)));
|
||||
|
||||
const columnHeaderId = showHeading && heading.replace(/ /g, '-');
|
||||
const columnHeaderId = showHeading && heading.replace(/ /g, "-");
|
||||
const header = showHeading && (
|
||||
<ColumnHeader icon={icon} active={active} type={heading} onClick={this.handleHeaderClick} columnHeaderId={columnHeaderId} />
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import classNames from "classnames";
|
||||
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { Icon } from "flavours/glitch/components/icon";
|
||||
|
||||
export default class ColumnHeader extends PureComponent {
|
||||
|
||||
@@ -21,14 +21,14 @@ export default class ColumnHeader extends PureComponent {
|
||||
|
||||
render () {
|
||||
const { icon, type, active, columnHeaderId } = this.props;
|
||||
let iconElement = '';
|
||||
let iconElement = "";
|
||||
|
||||
if (icon) {
|
||||
iconElement = <Icon id={icon} fixedWidth className='column-header__icon' />;
|
||||
}
|
||||
|
||||
return (
|
||||
<h1 className={classNames('column-header', { active })} id={columnHeaderId || null}>
|
||||
<h1 className={classNames("column-header", { active })} id={columnHeaderId || null}>
|
||||
<button onClick={this.handleClick}>
|
||||
{iconElement}
|
||||
{type}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import classNames from "classnames";
|
||||
import { NavLink } from "react-router-dom";
|
||||
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { Icon } from "flavours/glitch/components/icon";
|
||||
|
||||
const ColumnLink = ({ icon, text, to, onClick, href, method, badge, transparent, ...other }) => {
|
||||
const className = classNames('column-link', { 'column-link--transparent': transparent });
|
||||
const badgeElement = typeof badge !== 'undefined' ? <span className='column-link__badge'>{badge}</span> : null;
|
||||
const iconElement = typeof icon === 'string' ? <Icon id={icon} fixedWidth className='column-link__icon' /> : icon;
|
||||
const className = classNames("column-link", { "column-link--transparent": transparent });
|
||||
const badgeElement = typeof badge !== "undefined" ? <span className='column-link__badge'>{badge}</span> : null;
|
||||
const iconElement = typeof icon === "string" ? <Icon id={icon} fixedWidth className='column-link__icon' /> : icon;
|
||||
|
||||
if (href) {
|
||||
return (
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
|
||||
import Column from 'flavours/glitch/components/column';
|
||||
import ColumnHeader from 'flavours/glitch/components/column_header';
|
||||
import Column from "flavours/glitch/components/column";
|
||||
import ColumnHeader from "flavours/glitch/components/column_header";
|
||||
|
||||
export default class ColumnLoading extends ImmutablePureComponent {
|
||||
|
||||
@@ -14,8 +14,8 @@ export default class ColumnLoading extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
title: '',
|
||||
icon: '',
|
||||
title: "",
|
||||
icon: "",
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const ColumnSubheading = ({ text }) => {
|
||||
return (
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { Children, cloneElement } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { Children, cloneElement } from "react";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
|
||||
import { supportsPassiveEvents } from 'detect-passive-events';
|
||||
import { supportsPassiveEvents } from "detect-passive-events";
|
||||
|
||||
import { scrollRight } from 'flavours/glitch/scroll';
|
||||
import { scrollRight } from "flavours/glitch/scroll";
|
||||
|
||||
import BundleContainer from '../containers/bundle_container';
|
||||
import BundleContainer from "../containers/bundle_container";
|
||||
import {
|
||||
Compose,
|
||||
Notifications,
|
||||
@@ -21,27 +21,27 @@ import {
|
||||
BookmarkedStatuses,
|
||||
ListTimeline,
|
||||
Directory,
|
||||
} from '../util/async-components';
|
||||
} from "../util/async-components";
|
||||
|
||||
import BundleColumnError from './bundle_column_error';
|
||||
import ColumnLoading from './column_loading';
|
||||
import ComposePanel from './compose_panel';
|
||||
import DrawerLoading from './drawer_loading';
|
||||
import NavigationPanel from './navigation_panel';
|
||||
import BundleColumnError from "./bundle_column_error";
|
||||
import ColumnLoading from "./column_loading";
|
||||
import ComposePanel from "./compose_panel";
|
||||
import DrawerLoading from "./drawer_loading";
|
||||
import NavigationPanel from "./navigation_panel";
|
||||
|
||||
const componentMap = {
|
||||
'COMPOSE': Compose,
|
||||
'HOME': HomeTimeline,
|
||||
'NOTIFICATIONS': Notifications,
|
||||
'PUBLIC': PublicTimeline,
|
||||
'REMOTE': PublicTimeline,
|
||||
'COMMUNITY': CommunityTimeline,
|
||||
'HASHTAG': HashtagTimeline,
|
||||
'DIRECT': DirectTimeline,
|
||||
'FAVOURITES': FavouritedStatuses,
|
||||
'BOOKMARKS': BookmarkedStatuses,
|
||||
'LIST': ListTimeline,
|
||||
'DIRECTORY': Directory,
|
||||
"COMPOSE": Compose,
|
||||
"HOME": HomeTimeline,
|
||||
"NOTIFICATIONS": Notifications,
|
||||
"PUBLIC": PublicTimeline,
|
||||
"REMOTE": PublicTimeline,
|
||||
"COMMUNITY": CommunityTimeline,
|
||||
"HASHTAG": HashtagTimeline,
|
||||
"DIRECT": DirectTimeline,
|
||||
"FAVOURITES": FavouritedStatuses,
|
||||
"BOOKMARKS": BookmarkedStatuses,
|
||||
"LIST": ListTimeline,
|
||||
"DIRECTORY": Directory,
|
||||
};
|
||||
|
||||
export default class ColumnsArea extends ImmutablePureComponent {
|
||||
@@ -59,7 +59,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
// Corresponds to (max-width: $no-gap-breakpoint + 285px - 1px) in SCSS
|
||||
mediaQuery = 'matchMedia' in window && window.matchMedia('(max-width: 1174px)');
|
||||
mediaQuery = "matchMedia" in window && window.matchMedia("(max-width: 1174px)");
|
||||
|
||||
state = {
|
||||
renderComposePanel: !(this.mediaQuery && this.mediaQuery.matches),
|
||||
@@ -67,41 +67,41 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
||||
|
||||
componentDidMount() {
|
||||
if (!this.props.singleColumn) {
|
||||
this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : false);
|
||||
this.node.addEventListener("wheel", this.handleWheel, supportsPassiveEvents ? { passive: true } : false);
|
||||
}
|
||||
|
||||
if (this.mediaQuery) {
|
||||
if (this.mediaQuery.addEventListener) {
|
||||
this.mediaQuery.addEventListener('change', this.handleLayoutChange);
|
||||
this.mediaQuery.addEventListener("change", this.handleLayoutChange);
|
||||
} else {
|
||||
this.mediaQuery.addListener(this.handleLayoutChange);
|
||||
}
|
||||
this.setState({ renderComposePanel: !this.mediaQuery.matches });
|
||||
}
|
||||
|
||||
this.isRtlLayout = document.getElementsByTagName('body')[0].classList.contains('rtl');
|
||||
this.isRtlLayout = document.getElementsByTagName("body")[0].classList.contains("rtl");
|
||||
}
|
||||
|
||||
componentWillUpdate(nextProps) {
|
||||
if (this.props.singleColumn !== nextProps.singleColumn && nextProps.singleColumn) {
|
||||
this.node.removeEventListener('wheel', this.handleWheel);
|
||||
this.node.removeEventListener("wheel", this.handleWheel);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.singleColumn !== prevProps.singleColumn && !this.props.singleColumn) {
|
||||
this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : false);
|
||||
this.node.addEventListener("wheel", this.handleWheel, supportsPassiveEvents ? { passive: true } : false);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
if (!this.props.singleColumn) {
|
||||
this.node.removeEventListener('wheel', this.handleWheel);
|
||||
this.node.removeEventListener("wheel", this.handleWheel);
|
||||
}
|
||||
|
||||
if (this.mediaQuery) {
|
||||
if (this.mediaQuery.removeEventListener) {
|
||||
this.mediaQuery.removeEventListener('change', this.handleLayoutChange);
|
||||
this.mediaQuery.removeEventListener("change", this.handleLayoutChange);
|
||||
} else {
|
||||
this.mediaQuery.removeListener(this.handleLayoutChange);
|
||||
}
|
||||
@@ -120,7 +120,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
handleWheel = () => {
|
||||
if (typeof this._interruptScrollAnimation !== 'function') {
|
||||
if (typeof this._interruptScrollAnimation !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
renderLoading = columnId => () => {
|
||||
return columnId === 'COMPOSE' ? <DrawerLoading /> : <ColumnLoading multiColumn />;
|
||||
return columnId === "COMPOSE" ? <DrawerLoading /> : <ColumnLoading multiColumn />;
|
||||
};
|
||||
|
||||
renderError = (props) => {
|
||||
@@ -169,12 +169,12 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
||||
return (
|
||||
<div className='columns-area' ref={this.setRef}>
|
||||
{columns.map(column => {
|
||||
const params = column.get('params', null) === null ? null : column.get('params').toJS();
|
||||
const params = column.get("params", null) === null ? null : column.get("params").toJS();
|
||||
const other = params && params.other ? params.other : {};
|
||||
|
||||
return (
|
||||
<BundleContainer key={column.get('uuid')} fetchComponent={componentMap[column.get('id')]} loading={this.renderLoading(column.get('id'))} error={this.renderError}>
|
||||
{SpecificComponent => <SpecificComponent columnId={column.get('uuid')} params={params} multiColumn {...other} />}
|
||||
<BundleContainer key={column.get("uuid")} fetchComponent={componentMap[column.get("id")]} loading={this.renderLoading(column.get("id"))} error={this.renderError}>
|
||||
{SpecificComponent => <SpecificComponent columnId={column.get("uuid")} params={params} multiColumn {...other} />}
|
||||
</BundleContainer>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { connect } from 'react-redux';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import escapeTextContentForBrowser from 'escape-html';
|
||||
import escapeTextContentForBrowser from "escape-html";
|
||||
|
||||
import { closeModal } from 'flavours/glitch/actions/modal';
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import InlineAccount from 'flavours/glitch/components/inline_account';
|
||||
import MediaAttachments from 'flavours/glitch/components/media_attachments';
|
||||
import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp';
|
||||
import emojify from 'flavours/glitch/features/emoji/emoji';
|
||||
import { closeModal } from "flavours/glitch/actions/modal";
|
||||
import { IconButton } from "flavours/glitch/components/icon_button";
|
||||
import InlineAccount from "flavours/glitch/components/inline_account";
|
||||
import MediaAttachments from "flavours/glitch/components/media_attachments";
|
||||
import { RelativeTimestamp } from "flavours/glitch/components/relative_timestamp";
|
||||
import emojify from "flavours/glitch/features/emoji/emoji";
|
||||
|
||||
const mapStateToProps = (state, { statusId }) => ({
|
||||
language: state.getIn(['statuses', statusId, 'language']),
|
||||
versions: state.getIn(['history', statusId, 'items']),
|
||||
language: state.getIn(["statuses", statusId, "language"]),
|
||||
versions: state.getIn(["history", statusId, "items"]),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
@@ -45,18 +45,18 @@ class CompareHistoryModal extends PureComponent {
|
||||
const { index, versions, language, onClose } = this.props;
|
||||
const currentVersion = versions.get(index);
|
||||
|
||||
const emojiMap = currentVersion.get('emojis').reduce((obj, emoji) => {
|
||||
obj[`:${emoji.get('shortcode')}:`] = emoji.toJS();
|
||||
const emojiMap = currentVersion.get("emojis").reduce((obj, emoji) => {
|
||||
obj[`:${emoji.get("shortcode")}:`] = emoji.toJS();
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
const content = { __html: emojify(currentVersion.get('content'), emojiMap) };
|
||||
const spoilerContent = { __html: emojify(escapeTextContentForBrowser(currentVersion.get('spoiler_text')), emojiMap) };
|
||||
const content = { __html: emojify(currentVersion.get("content"), emojiMap) };
|
||||
const spoilerContent = { __html: emojify(escapeTextContentForBrowser(currentVersion.get("spoiler_text")), emojiMap) };
|
||||
|
||||
const formattedDate = <RelativeTimestamp timestamp={currentVersion.get('created_at')} short={false} />;
|
||||
const formattedName = <InlineAccount accountId={currentVersion.get('account')} />;
|
||||
const formattedDate = <RelativeTimestamp timestamp={currentVersion.get("created_at")} short={false} />;
|
||||
const formattedName = <InlineAccount accountId={currentVersion.get("account")} />;
|
||||
|
||||
const label = currentVersion.get('original') ? (
|
||||
const label = currentVersion.get("original") ? (
|
||||
<FormattedMessage id='status.history.created' defaultMessage='{name} created {date}' values={{ name: formattedName, date: formattedDate }} />
|
||||
) : (
|
||||
<FormattedMessage id='status.history.edited' defaultMessage='{name} edited {date}' values={{ name: formattedName, date: formattedDate }} />
|
||||
@@ -71,7 +71,7 @@ class CompareHistoryModal extends PureComponent {
|
||||
|
||||
<div className='compare-history-modal__container'>
|
||||
<div className='status__content'>
|
||||
{currentVersion.get('spoiler_text').length > 0 && (
|
||||
{currentVersion.get("spoiler_text").length > 0 && (
|
||||
<>
|
||||
<div className='translate' dangerouslySetInnerHTML={spoilerContent} lang={language} />
|
||||
<hr />
|
||||
@@ -80,16 +80,16 @@ class CompareHistoryModal extends PureComponent {
|
||||
|
||||
<div className='status__content__text status__content__text--visible translate' dangerouslySetInnerHTML={content} lang={language} />
|
||||
|
||||
{!!currentVersion.get('poll') && (
|
||||
{!!currentVersion.get("poll") && (
|
||||
<div className='poll'>
|
||||
<ul>
|
||||
{currentVersion.getIn(['poll', 'options']).map(option => (
|
||||
<li key={option.get('title')}>
|
||||
{currentVersion.getIn(["poll", "options"]).map(option => (
|
||||
<li key={option.get("title")}>
|
||||
<span className='poll__input disabled' />
|
||||
|
||||
<span
|
||||
className='poll__option__text translate'
|
||||
dangerouslySetInnerHTML={{ __html: emojify(escapeTextContentForBrowser(option.get('title')), emojiMap) }}
|
||||
dangerouslySetInnerHTML={{ __html: emojify(escapeTextContentForBrowser(option.get("title")), emojiMap) }}
|
||||
lang={language}
|
||||
/>
|
||||
</li>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { mountCompose, unmountCompose } from 'flavours/glitch/actions/compose';
|
||||
import ServerBanner from 'flavours/glitch/components/server_banner';
|
||||
import ComposeFormContainer from 'flavours/glitch/features/compose/containers/compose_form_container';
|
||||
import NavigationContainer from 'flavours/glitch/features/compose/containers/navigation_container';
|
||||
import SearchContainer from 'flavours/glitch/features/compose/containers/search_container';
|
||||
import { mountCompose, unmountCompose } from "flavours/glitch/actions/compose";
|
||||
import ServerBanner from "flavours/glitch/components/server_banner";
|
||||
import ComposeFormContainer from "flavours/glitch/features/compose/containers/compose_form_container";
|
||||
import NavigationContainer from "flavours/glitch/features/compose/containers/navigation_container";
|
||||
import SearchContainer from "flavours/glitch/features/compose/containers/search_container";
|
||||
|
||||
import LinkFooter from './link_footer';
|
||||
import LinkFooter from "./link_footer";
|
||||
|
||||
|
||||
class ComposePanel extends PureComponent {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { injectIntl, FormattedMessage } from "react-intl";
|
||||
|
||||
import Button from 'flavours/glitch/components/button';
|
||||
import Button from "flavours/glitch/components/button";
|
||||
|
||||
class ConfirmationModal extends PureComponent {
|
||||
|
||||
@@ -67,7 +67,7 @@ class ConfirmationModal extends PureComponent {
|
||||
{ onDoNotAsk && (
|
||||
<div className='confirmation-modal__do_not_ask_again'>
|
||||
<input type='checkbox' id='confirmation-modal__do_not_ask_again-checkbox' ref={this.setDoNotAskRef} />
|
||||
<label for='confirmation-modal__do_not_ask_again-checkbox'>
|
||||
<label htmlFor='confirmation-modal__do_not_ask_again-checkbox'>
|
||||
<FormattedMessage id='confirmation_modal.do_not_ask_again' defaultMessage='Do not ask for confirmation again' />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from "react-intl";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
|
||||
import Button from 'flavours/glitch/components/button';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import illustration from 'flavours/glitch/images/logo_warn_glitch.svg';
|
||||
import Button from "flavours/glitch/components/button";
|
||||
import { Icon } from "flavours/glitch/components/icon";
|
||||
import illustration from "flavours/glitch/images/logo_warn_glitch.svg";
|
||||
|
||||
const messages = defineMessages({
|
||||
discardChanges: { id: 'confirmations.deprecated_settings.confirm', defaultMessage: 'Use Mastodon preferences' },
|
||||
user_setting_disable_swiping: { id: 'settings.swipe_to_change_columns', defaultMessage: 'Allow swiping to change columns (Mobile only)' },
|
||||
discardChanges: { id: "confirmations.deprecated_settings.confirm", defaultMessage: "Use Mastodon preferences" },
|
||||
user_setting_disable_swiping: { id: "settings.swipe_to_change_columns", defaultMessage: "Allow swiping to change columns (Mobile only)" },
|
||||
});
|
||||
|
||||
class DeprecatedSettingsModal extends PureComponent {
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
||||
import { FormattedMessage, defineMessages, injectIntl } from "react-intl";
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { disabledAccountId, movedToAccountId, domain } from 'flavours/glitch/initial_state';
|
||||
import { logOut } from 'flavours/glitch/utils/log_out';
|
||||
import { openModal } from "flavours/glitch/actions/modal";
|
||||
import { disabledAccountId, movedToAccountId, domain } from "flavours/glitch/initial_state";
|
||||
import { logOut } from "flavours/glitch/utils/log_out";
|
||||
|
||||
const messages = defineMessages({
|
||||
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
||||
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
|
||||
logoutMessage: { id: "confirmations.logout.message", defaultMessage: "Are you sure you want to log out?" },
|
||||
logoutConfirm: { id: "confirmations.logout.confirm", defaultMessage: "Log out" },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
disabledAcct: state.getIn(['accounts', disabledAccountId, 'acct']),
|
||||
movedToAcct: movedToAccountId ? state.getIn(['accounts', movedToAccountId, 'acct']) : undefined,
|
||||
disabledAcct: state.getIn(["accounts", disabledAccountId, "acct"]),
|
||||
movedToAcct: movedToAccountId ? state.getIn(["accounts", movedToAccountId, "acct"]) : undefined,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||
onLogout () {
|
||||
dispatch(openModal({
|
||||
modalType: 'CONFIRM',
|
||||
modalType: "CONFIRM",
|
||||
modalProps: {
|
||||
message: intl.formatMessage(messages.logoutMessage),
|
||||
confirm: intl.formatMessage(messages.logoutConfirm),
|
||||
@@ -71,7 +71,7 @@ class DisabledAccountBanner extends PureComponent {
|
||||
defaultMessage='Your account {disabledAccount} is currently disabled because you moved to {movedToAccount}.'
|
||||
values={{
|
||||
disabledAccount: disabledAccountLink,
|
||||
movedToAccount: <Link to={`/@${movedToAcct}`}>{movedToAcct.includes('@') ? movedToAcct : `${movedToAcct}@${domain}`}</Link>,
|
||||
movedToAccount: <Link to={`/@${movedToAcct}`}>{movedToAcct.includes("@") ? movedToAcct : `${movedToAcct}@${domain}`}</Link>,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
|
||||
@@ -1,96 +1,96 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import classNames from "classnames";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import Atrament from 'atrament'; // the doodling library
|
||||
import { debounce, mapValues } from 'lodash';
|
||||
import Atrament from "atrament"; // the doodling library
|
||||
import { debounce, mapValues } from "lodash";
|
||||
|
||||
import { doodleSet, uploadCompose } from 'flavours/glitch/actions/compose';
|
||||
import Button from 'flavours/glitch/components/button';
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import { doodleSet, uploadCompose } from "flavours/glitch/actions/compose";
|
||||
import Button from "flavours/glitch/components/button";
|
||||
import { IconButton } from "flavours/glitch/components/icon_button";
|
||||
// palette nicked from MyPaint, CC0
|
||||
const palette = [
|
||||
['rgb( 0, 0, 0)', 'Black'],
|
||||
['rgb( 38, 38, 38)', 'Gray 15'],
|
||||
['rgb( 77, 77, 77)', 'Grey 30'],
|
||||
['rgb(128, 128, 128)', 'Grey 50'],
|
||||
['rgb(171, 171, 171)', 'Grey 67'],
|
||||
['rgb(217, 217, 217)', 'Grey 85'],
|
||||
['rgb(255, 255, 255)', 'White'],
|
||||
['rgb(128, 0, 0)', 'Maroon'],
|
||||
['rgb(209, 0, 0)', 'English-red'],
|
||||
['rgb(255, 54, 34)', 'Tomato'],
|
||||
['rgb(252, 60, 3)', 'Orange-red'],
|
||||
['rgb(255, 140, 105)', 'Salmon'],
|
||||
['rgb(252, 232, 32)', 'Cadium-yellow'],
|
||||
['rgb(243, 253, 37)', 'Lemon yellow'],
|
||||
['rgb(121, 5, 35)', 'Dark crimson'],
|
||||
['rgb(169, 32, 62)', 'Deep carmine'],
|
||||
['rgb(255, 140, 0)', 'Orange'],
|
||||
['rgb(255, 168, 18)', 'Dark tangerine'],
|
||||
['rgb(217, 144, 88)', 'Persian orange'],
|
||||
['rgb(194, 178, 128)', 'Sand'],
|
||||
['rgb(255, 229, 180)', 'Peach'],
|
||||
['rgb(100, 54, 46)', 'Bole'],
|
||||
['rgb(108, 41, 52)', 'Dark cordovan'],
|
||||
['rgb(163, 65, 44)', 'Chestnut'],
|
||||
['rgb(228, 136, 100)', 'Dark salmon'],
|
||||
['rgb(255, 195, 143)', 'Apricot'],
|
||||
['rgb(255, 219, 188)', 'Unbleached silk'],
|
||||
['rgb(242, 227, 198)', 'Straw'],
|
||||
['rgb( 53, 19, 13)', 'Bistre'],
|
||||
['rgb( 84, 42, 14)', 'Dark chocolate'],
|
||||
['rgb(102, 51, 43)', 'Burnt sienna'],
|
||||
['rgb(184, 66, 0)', 'Sienna'],
|
||||
['rgb(216, 153, 12)', 'Yellow ochre'],
|
||||
['rgb(210, 180, 140)', 'Tan'],
|
||||
['rgb(232, 204, 144)', 'Dark wheat'],
|
||||
['rgb( 0, 49, 83)', 'Prussian blue'],
|
||||
['rgb( 48, 69, 119)', 'Dark grey blue'],
|
||||
['rgb( 0, 71, 171)', 'Cobalt blue'],
|
||||
['rgb( 31, 117, 254)', 'Blue'],
|
||||
['rgb(120, 180, 255)', 'Bright french blue'],
|
||||
['rgb(171, 200, 255)', 'Bright steel blue'],
|
||||
['rgb(208, 231, 255)', 'Ice blue'],
|
||||
['rgb( 30, 51, 58)', 'Medium jungle green'],
|
||||
['rgb( 47, 79, 79)', 'Dark slate grey'],
|
||||
['rgb( 74, 104, 93)', 'Dark grullo green'],
|
||||
['rgb( 0, 128, 128)', 'Teal'],
|
||||
['rgb( 67, 170, 176)', 'Turquoise'],
|
||||
['rgb(109, 174, 199)', 'Cerulean frost'],
|
||||
['rgb(173, 217, 186)', 'Tiffany green'],
|
||||
['rgb( 22, 34, 29)', 'Gray-asparagus'],
|
||||
['rgb( 36, 48, 45)', 'Medium dark teal'],
|
||||
['rgb( 74, 104, 93)', 'Xanadu'],
|
||||
['rgb(119, 198, 121)', 'Mint'],
|
||||
['rgb(175, 205, 182)', 'Timberwolf'],
|
||||
['rgb(185, 245, 246)', 'Celeste'],
|
||||
['rgb(193, 255, 234)', 'Aquamarine'],
|
||||
['rgb( 29, 52, 35)', 'Cal Poly Pomona'],
|
||||
['rgb( 1, 68, 33)', 'Forest green'],
|
||||
['rgb( 42, 128, 0)', 'Napier green'],
|
||||
['rgb(128, 128, 0)', 'Olive'],
|
||||
['rgb( 65, 156, 105)', 'Sea green'],
|
||||
['rgb(189, 246, 29)', 'Green-yellow'],
|
||||
['rgb(231, 244, 134)', 'Bright chartreuse'],
|
||||
['rgb(138, 23, 137)', 'Purple'],
|
||||
['rgb( 78, 39, 138)', 'Violet'],
|
||||
['rgb(193, 75, 110)', 'Dark thulian pink'],
|
||||
['rgb(222, 49, 99)', 'Cerise'],
|
||||
['rgb(255, 20, 147)', 'Deep pink'],
|
||||
['rgb(255, 102, 204)', 'Rose pink'],
|
||||
['rgb(255, 203, 219)', 'Pink'],
|
||||
['rgb(255, 255, 255)', 'White'],
|
||||
['rgb(229, 17, 1)', 'RGB Red'],
|
||||
['rgb( 0, 255, 0)', 'RGB Green'],
|
||||
['rgb( 0, 0, 255)', 'RGB Blue'],
|
||||
['rgb( 0, 255, 255)', 'CMYK Cyan'],
|
||||
['rgb(255, 0, 255)', 'CMYK Magenta'],
|
||||
['rgb(255, 255, 0)', 'CMYK Yellow'],
|
||||
["rgb( 0, 0, 0)", "Black"],
|
||||
["rgb( 38, 38, 38)", "Gray 15"],
|
||||
["rgb( 77, 77, 77)", "Grey 30"],
|
||||
["rgb(128, 128, 128)", "Grey 50"],
|
||||
["rgb(171, 171, 171)", "Grey 67"],
|
||||
["rgb(217, 217, 217)", "Grey 85"],
|
||||
["rgb(255, 255, 255)", "White"],
|
||||
["rgb(128, 0, 0)", "Maroon"],
|
||||
["rgb(209, 0, 0)", "English-red"],
|
||||
["rgb(255, 54, 34)", "Tomato"],
|
||||
["rgb(252, 60, 3)", "Orange-red"],
|
||||
["rgb(255, 140, 105)", "Salmon"],
|
||||
["rgb(252, 232, 32)", "Cadium-yellow"],
|
||||
["rgb(243, 253, 37)", "Lemon yellow"],
|
||||
["rgb(121, 5, 35)", "Dark crimson"],
|
||||
["rgb(169, 32, 62)", "Deep carmine"],
|
||||
["rgb(255, 140, 0)", "Orange"],
|
||||
["rgb(255, 168, 18)", "Dark tangerine"],
|
||||
["rgb(217, 144, 88)", "Persian orange"],
|
||||
["rgb(194, 178, 128)", "Sand"],
|
||||
["rgb(255, 229, 180)", "Peach"],
|
||||
["rgb(100, 54, 46)", "Bole"],
|
||||
["rgb(108, 41, 52)", "Dark cordovan"],
|
||||
["rgb(163, 65, 44)", "Chestnut"],
|
||||
["rgb(228, 136, 100)", "Dark salmon"],
|
||||
["rgb(255, 195, 143)", "Apricot"],
|
||||
["rgb(255, 219, 188)", "Unbleached silk"],
|
||||
["rgb(242, 227, 198)", "Straw"],
|
||||
["rgb( 53, 19, 13)", "Bistre"],
|
||||
["rgb( 84, 42, 14)", "Dark chocolate"],
|
||||
["rgb(102, 51, 43)", "Burnt sienna"],
|
||||
["rgb(184, 66, 0)", "Sienna"],
|
||||
["rgb(216, 153, 12)", "Yellow ochre"],
|
||||
["rgb(210, 180, 140)", "Tan"],
|
||||
["rgb(232, 204, 144)", "Dark wheat"],
|
||||
["rgb( 0, 49, 83)", "Prussian blue"],
|
||||
["rgb( 48, 69, 119)", "Dark grey blue"],
|
||||
["rgb( 0, 71, 171)", "Cobalt blue"],
|
||||
["rgb( 31, 117, 254)", "Blue"],
|
||||
["rgb(120, 180, 255)", "Bright french blue"],
|
||||
["rgb(171, 200, 255)", "Bright steel blue"],
|
||||
["rgb(208, 231, 255)", "Ice blue"],
|
||||
["rgb( 30, 51, 58)", "Medium jungle green"],
|
||||
["rgb( 47, 79, 79)", "Dark slate grey"],
|
||||
["rgb( 74, 104, 93)", "Dark grullo green"],
|
||||
["rgb( 0, 128, 128)", "Teal"],
|
||||
["rgb( 67, 170, 176)", "Turquoise"],
|
||||
["rgb(109, 174, 199)", "Cerulean frost"],
|
||||
["rgb(173, 217, 186)", "Tiffany green"],
|
||||
["rgb( 22, 34, 29)", "Gray-asparagus"],
|
||||
["rgb( 36, 48, 45)", "Medium dark teal"],
|
||||
["rgb( 74, 104, 93)", "Xanadu"],
|
||||
["rgb(119, 198, 121)", "Mint"],
|
||||
["rgb(175, 205, 182)", "Timberwolf"],
|
||||
["rgb(185, 245, 246)", "Celeste"],
|
||||
["rgb(193, 255, 234)", "Aquamarine"],
|
||||
["rgb( 29, 52, 35)", "Cal Poly Pomona"],
|
||||
["rgb( 1, 68, 33)", "Forest green"],
|
||||
["rgb( 42, 128, 0)", "Napier green"],
|
||||
["rgb(128, 128, 0)", "Olive"],
|
||||
["rgb( 65, 156, 105)", "Sea green"],
|
||||
["rgb(189, 246, 29)", "Green-yellow"],
|
||||
["rgb(231, 244, 134)", "Bright chartreuse"],
|
||||
["rgb(138, 23, 137)", "Purple"],
|
||||
["rgb( 78, 39, 138)", "Violet"],
|
||||
["rgb(193, 75, 110)", "Dark thulian pink"],
|
||||
["rgb(222, 49, 99)", "Cerise"],
|
||||
["rgb(255, 20, 147)", "Deep pink"],
|
||||
["rgb(255, 102, 204)", "Rose pink"],
|
||||
["rgb(255, 203, 219)", "Pink"],
|
||||
["rgb(255, 255, 255)", "White"],
|
||||
["rgb(229, 17, 1)", "RGB Red"],
|
||||
["rgb( 0, 255, 0)", "RGB Green"],
|
||||
["rgb( 0, 0, 255)", "RGB Blue"],
|
||||
["rgb( 0, 255, 255)", "CMYK Cyan"],
|
||||
["rgb(255, 0, 255)", "CMYK Magenta"],
|
||||
["rgb(255, 255, 0)", "CMYK Yellow"],
|
||||
];
|
||||
|
||||
// re-arrange to the right order for display
|
||||
@@ -105,7 +105,7 @@ for (let row = 0; row < 7; row++) {
|
||||
// Utility for converting base64 image to binary for upload
|
||||
// https://stackoverflow.com/questions/35940290/how-to-convert-base64-string-to-javascript-file-object-like-as-from-file-input-f
|
||||
function dataURLtoFile(dataurl, filename) {
|
||||
let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
|
||||
let arr = dataurl.split(","), mime = arr[0].match(/:(.*?);/)[1],
|
||||
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
|
||||
while(n--){
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
@@ -114,16 +114,16 @@ function dataURLtoFile(dataurl, filename) {
|
||||
}
|
||||
/** Doodle canvas size options */
|
||||
const DOODLE_SIZES = {
|
||||
normal: [500, 500, 'Square 500'],
|
||||
tootbanner: [702, 330, 'Tootbanner'],
|
||||
s640x480: [640, 480, '640×480 - 480p'],
|
||||
s800x600: [800, 600, '800×600 - SVGA'],
|
||||
s720x480: [720, 405, '720x405 - 16:9'],
|
||||
normal: [500, 500, "Square 500"],
|
||||
tootbanner: [702, 330, "Tootbanner"],
|
||||
s640x480: [640, 480, "640×480 - 480p"],
|
||||
s800x600: [800, 600, "800×600 - SVGA"],
|
||||
s720x480: [720, 405, "720x405 - 16:9"],
|
||||
};
|
||||
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
options: state.getIn(['compose', 'doodle']),
|
||||
options: state.getIn(["compose", "doodle"]),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
@@ -166,7 +166,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
|
||||
/** Foreground color */
|
||||
get fg () {
|
||||
return this.props.options.get('fg');
|
||||
return this.props.options.get("fg");
|
||||
}
|
||||
set fg (value) {
|
||||
this.props.setOpt({ fg: value });
|
||||
@@ -174,7 +174,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
|
||||
/** Background color */
|
||||
get bg () {
|
||||
return this.props.options.get('bg');
|
||||
return this.props.options.get("bg");
|
||||
}
|
||||
set bg (value) {
|
||||
this.props.setOpt({ bg: value });
|
||||
@@ -182,7 +182,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
|
||||
/** Swap Fg and Bg for drawing */
|
||||
get swapped () {
|
||||
return this.props.options.get('swapped');
|
||||
return this.props.options.get("swapped");
|
||||
}
|
||||
set swapped (value) {
|
||||
this.props.setOpt({ swapped: value });
|
||||
@@ -190,7 +190,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
|
||||
/** Mode - 'draw' or 'fill' */
|
||||
get mode () {
|
||||
return this.props.options.get('mode');
|
||||
return this.props.options.get("mode");
|
||||
}
|
||||
set mode (value) {
|
||||
this.props.setOpt({ mode: value });
|
||||
@@ -198,7 +198,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
|
||||
/** Base line weight */
|
||||
get weight () {
|
||||
return this.props.options.get('weight');
|
||||
return this.props.options.get("weight");
|
||||
}
|
||||
set weight (value) {
|
||||
this.props.setOpt({ weight: value });
|
||||
@@ -206,7 +206,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
|
||||
/** Drawing opacity */
|
||||
get opacity () {
|
||||
return this.props.options.get('opacity');
|
||||
return this.props.options.get("opacity");
|
||||
}
|
||||
set opacity (value) {
|
||||
this.props.setOpt({ opacity: value });
|
||||
@@ -214,7 +214,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
|
||||
/** Adaptive stroke - change width with speed */
|
||||
get adaptiveStroke () {
|
||||
return this.props.options.get('adaptiveStroke');
|
||||
return this.props.options.get("adaptiveStroke");
|
||||
}
|
||||
set adaptiveStroke (value) {
|
||||
this.props.setOpt({ adaptiveStroke: value });
|
||||
@@ -222,7 +222,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
|
||||
/** Smoothing (for mouse drawing) */
|
||||
get smoothing () {
|
||||
return this.props.options.get('smoothing');
|
||||
return this.props.options.get("smoothing");
|
||||
}
|
||||
set smoothing (value) {
|
||||
this.props.setOpt({ smoothing: value });
|
||||
@@ -230,7 +230,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
|
||||
/** Size preset */
|
||||
get size () {
|
||||
return this.props.options.get('size');
|
||||
return this.props.options.get("size");
|
||||
}
|
||||
set size (value) {
|
||||
this.props.setOpt({ size: value });
|
||||
@@ -243,27 +243,29 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
* @param {KeyboardEvent} e
|
||||
*/
|
||||
handleKeyUp = (e) => {
|
||||
if (e.target.nodeName === 'INPUT') return;
|
||||
if (e.target.nodeName === "INPUT") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.key === 'Delete') {
|
||||
if (e.key === "Delete") {
|
||||
e.preventDefault();
|
||||
this.handleClearBtn();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.key === 'Backspace' || (e.key === 'z' && (e.ctrlKey || e.metaKey))) {
|
||||
if (e.key === "Backspace" || (e.key === "z" && (e.ctrlKey || e.metaKey))) {
|
||||
e.preventDefault();
|
||||
this.undo();
|
||||
}
|
||||
|
||||
if (e.key === 'Control' || e.key === 'Meta') {
|
||||
if (e.key === "Control" || e.key === "Meta") {
|
||||
this.controlHeld = false;
|
||||
this.swapped = false;
|
||||
}
|
||||
|
||||
if (e.key === 'Shift') {
|
||||
if (e.key === "Shift") {
|
||||
this.shiftHeld = false;
|
||||
this.mode = 'draw';
|
||||
this.mode = "draw";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -272,14 +274,14 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
* @param {KeyboardEvent} e
|
||||
*/
|
||||
handleKeyDown = (e) => {
|
||||
if (e.key === 'Control' || e.key === 'Meta') {
|
||||
if (e.key === "Control" || e.key === "Meta") {
|
||||
this.controlHeld = true;
|
||||
this.swapped = true;
|
||||
}
|
||||
|
||||
if (e.key === 'Shift') {
|
||||
if (e.key === "Shift") {
|
||||
this.shiftHeld = true;
|
||||
this.mode = 'fill';
|
||||
this.mode = "fill";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -290,17 +292,19 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
this.controlHeld = false;
|
||||
this.shiftHeld = false;
|
||||
this.swapped = false;
|
||||
window.addEventListener('keyup', this.handleKeyUp, false);
|
||||
window.addEventListener('keydown', this.handleKeyDown, false);
|
||||
window.addEventListener("keyup", this.handleKeyUp, false);
|
||||
window.addEventListener("keydown", this.handleKeyDown, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tear component down
|
||||
*/
|
||||
componentWillUnmount () {
|
||||
window.removeEventListener('keyup', this.handleKeyUp, false);
|
||||
window.removeEventListener('keydown', this.handleKeyDown, false);
|
||||
if (this.sketcher) this.sketcher.destroy();
|
||||
window.removeEventListener("keyup", this.handleKeyUp, false);
|
||||
window.removeEventListener("keydown", this.handleKeyDown, false);
|
||||
if (this.sketcher) {
|
||||
this.sketcher.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -311,37 +315,37 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
setCanvasRef = (elem) => {
|
||||
this.canvas = elem;
|
||||
if (elem) {
|
||||
elem.addEventListener('dirty', () => {
|
||||
elem.addEventListener("dirty", () => {
|
||||
this.saveUndo();
|
||||
this.sketcher._dirty = false;
|
||||
});
|
||||
|
||||
elem.addEventListener('click', () => {
|
||||
elem.addEventListener("click", () => {
|
||||
// sketcher bug - does not fire dirty on fill
|
||||
if (this.mode === 'fill') {
|
||||
if (this.mode === "fill") {
|
||||
this.saveUndo();
|
||||
}
|
||||
});
|
||||
|
||||
// prevent context menu
|
||||
elem.addEventListener('contextmenu', (e) => {
|
||||
elem.addEventListener("contextmenu", (e) => {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
elem.addEventListener('mousedown', (e) => {
|
||||
elem.addEventListener("mousedown", (e) => {
|
||||
if (e.button === 2) {
|
||||
this.swapped = true;
|
||||
}
|
||||
});
|
||||
|
||||
elem.addEventListener('mouseup', (e) => {
|
||||
elem.addEventListener("mouseup", (e) => {
|
||||
if (e.button === 2) {
|
||||
this.swapped = this.controlHeld;
|
||||
}
|
||||
});
|
||||
|
||||
this.initSketcher(elem);
|
||||
this.mode = 'draw'; // Reset mode - it's confusing if left at 'fill'
|
||||
this.mode = "draw"; // Reset mode - it's confusing if left at 'fill'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -352,7 +356,9 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
initSketcher (canvas = null) {
|
||||
const sizepreset = DOODLE_SIZES[this.size];
|
||||
|
||||
if (this.sketcher) this.sketcher.destroy();
|
||||
if (this.sketcher) {
|
||||
this.sketcher.destroy();
|
||||
}
|
||||
this.sketcher = new Atrament(canvas || this.canvas, sizepreset[0], sizepreset[1]);
|
||||
|
||||
if (canvas) {
|
||||
@@ -368,7 +374,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
*/
|
||||
onDoneButton = () => {
|
||||
const dataUrl = this.sketcher.toImage();
|
||||
const file = dataURLtoFile(dataUrl, 'doodle.png');
|
||||
const file = dataURLtoFile(dataUrl, "doodle.png");
|
||||
this.props.submit(file);
|
||||
this.props.onClose(); // close dialog
|
||||
};
|
||||
@@ -377,7 +383,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
* Cancel button handler
|
||||
*/
|
||||
onCancelButton = () => {
|
||||
if (this.undos.length > 1 && !confirm('Discard doodle? All changes will be lost!')) {
|
||||
if (this.undos.length > 1 && !confirm("Discard doodle? All changes will be lost!")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -388,9 +394,13 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
* Update sketcher options based on state
|
||||
*/
|
||||
updateSketcherSettings () {
|
||||
if (!this.sketcher) return;
|
||||
if (!this.sketcher) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.oldSize !== this.size) this.initSketcher();
|
||||
if (this.oldSize !== this.size) {
|
||||
this.initSketcher();
|
||||
}
|
||||
|
||||
this.sketcher.color = (this.swapped ? this.bg : this.fg);
|
||||
this.sketcher.opacity = this.opacity;
|
||||
@@ -476,7 +486,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
* @param {MouseEvent<HTMLButtonElement>} e - event
|
||||
*/
|
||||
setModeDraw = (e) => {
|
||||
this.mode = 'draw';
|
||||
this.mode = "draw";
|
||||
e.target.blur();
|
||||
};
|
||||
|
||||
@@ -485,7 +495,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
* @param {MouseEvent<HTMLButtonElement>} e - event
|
||||
*/
|
||||
setModeFill = (e) => {
|
||||
this.mode = 'fill';
|
||||
this.mode = "fill";
|
||||
e.target.blur();
|
||||
};
|
||||
|
||||
@@ -521,9 +531,11 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
*/
|
||||
changeSize = (e) => {
|
||||
let newSize = e.target.value;
|
||||
if (newSize === this.oldSize) return;
|
||||
if (newSize === this.oldSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.undos.length > 1 && !confirm('Change canvas size? This will erase your current drawing!')) {
|
||||
if (this.undos.length > 1 && !confirm("Change canvas size? This will erase your current drawing!")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -531,7 +543,7 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
handleClearBtn = () => {
|
||||
if (this.undos.length > 1 && !confirm('Clear canvas? This will erase your current drawing!')) {
|
||||
if (this.undos.length > 1 && !confirm("Clear canvas? This will erase your current drawing!")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -584,8 +596,8 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
</div>
|
||||
</div>
|
||||
<div className='doodle-toolbar'>
|
||||
<IconButton icon='pencil' title='Draw' label='Draw' onClick={this.setModeDraw} size={18} active={this.mode === 'draw'} inverted />
|
||||
<IconButton icon='bath' title='Fill' label='Fill' onClick={this.setModeFill} size={18} active={this.mode === 'fill'} inverted />
|
||||
<IconButton icon='pencil' title='Draw' label='Draw' onClick={this.setModeDraw} size={18} active={this.mode === "draw"} inverted />
|
||||
<IconButton icon='bath' title='Fill' label='Fill' onClick={this.setModeFill} size={18} active={this.mode === "fill"} inverted />
|
||||
<IconButton icon='undo' title='Undo' label='Undo' onClick={this.undo} size={18} inverted />
|
||||
<IconButton icon='trash' title='Clear' label='Clear' onClick={this.handleClearBtn} size={18} inverted />
|
||||
</div>
|
||||
@@ -602,8 +614,8 @@ class DoodleModal extends ImmutablePureComponent {
|
||||
data-color={c[0]}
|
||||
title={c[1]}
|
||||
className={classNames({
|
||||
'foreground': this.fg === c[0],
|
||||
'background': this.bg === c[0],
|
||||
"foreground": this.fg === c[0],
|
||||
"background": this.bg === c[0],
|
||||
})}
|
||||
/>,
|
||||
)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage, injectIntl } from "react-intl";
|
||||
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
|
||||
import api from 'flavours/glitch/api';
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import api from "flavours/glitch/api";
|
||||
import { IconButton } from "flavours/glitch/components/icon_button";
|
||||
|
||||
const messages = defineMessages({
|
||||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||
close: { id: "lightbox.close", defaultMessage: "Close" },
|
||||
});
|
||||
|
||||
class EmbedModal extends ImmutablePureComponent {
|
||||
@@ -66,7 +66,7 @@ class EmbedModal extends ImmutablePureComponent {
|
||||
<FormattedMessage id='status.embed' defaultMessage='Embed' />
|
||||
</div>
|
||||
|
||||
<div className='report-modal__container embed-modal__container' style={{ display: 'block' }}>
|
||||
<div className='report-modal__container embed-modal__container' style={{ display: "block" }}>
|
||||
<p className='hint'>
|
||||
<FormattedMessage id='embed.instructions' defaultMessage='Embed this status on your website by copying the code below.' />
|
||||
</p>
|
||||
@@ -75,7 +75,7 @@ class EmbedModal extends ImmutablePureComponent {
|
||||
type='text'
|
||||
className='embed-modal__html'
|
||||
readOnly
|
||||
value={oembed && oembed.html || ''}
|
||||
value={oembed && oembed.html || ""}
|
||||
onClick={this.handleTextareaClick}
|
||||
/>
|
||||
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from "react-intl";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import classNames from "classnames";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
|
||||
import AttachmentList from 'flavours/glitch/components/attachment_list';
|
||||
import { Avatar } from 'flavours/glitch/components/avatar';
|
||||
import Button from 'flavours/glitch/components/button';
|
||||
import { DisplayName } from 'flavours/glitch/components/display_name';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp';
|
||||
import StatusContent from 'flavours/glitch/components/status_content';
|
||||
import VisibilityIcon from 'flavours/glitch/components/status_visibility_icon';
|
||||
import AttachmentList from "flavours/glitch/components/attachment_list";
|
||||
import { Avatar } from "flavours/glitch/components/avatar";
|
||||
import Button from "flavours/glitch/components/button";
|
||||
import { DisplayName } from "flavours/glitch/components/display_name";
|
||||
import { Icon } from "flavours/glitch/components/icon";
|
||||
import { RelativeTimestamp } from "flavours/glitch/components/relative_timestamp";
|
||||
import StatusContent from "flavours/glitch/components/status_content";
|
||||
import VisibilityIcon from "flavours/glitch/components/status_visibility_icon";
|
||||
|
||||
const messages = defineMessages({
|
||||
favourite: { id: 'status.favourite', defaultMessage: 'Favourite' },
|
||||
favourite: { id: "status.favourite", defaultMessage: "Favourite" },
|
||||
});
|
||||
|
||||
class FavouriteModal extends ImmutablePureComponent {
|
||||
@@ -46,7 +46,7 @@ class FavouriteModal extends ImmutablePureComponent {
|
||||
if (e.button === 0) {
|
||||
e.preventDefault();
|
||||
this.props.onClose();
|
||||
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
|
||||
this.context.router.history.push(`/@${this.props.status.getIn(["account", "acct"])}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -60,31 +60,31 @@ class FavouriteModal extends ImmutablePureComponent {
|
||||
return (
|
||||
<div className='modal-root__modal boost-modal'>
|
||||
<div className='boost-modal__container'>
|
||||
<div className={classNames('status', `status-${status.get('visibility')}`, 'light')}>
|
||||
<div className={classNames("status", `status-${status.get("visibility")}`, "light")}>
|
||||
<div className='boost-modal__status-header'>
|
||||
<div className='boost-modal__status-time'>
|
||||
<a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
||||
<VisibilityIcon visibility={status.get('visibility')} />
|
||||
<RelativeTimestamp timestamp={status.get('created_at')} />
|
||||
<a href={status.get("url")} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
|
||||
<VisibilityIcon visibility={status.get("visibility")} />
|
||||
<RelativeTimestamp timestamp={status.get("created_at")} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name'>
|
||||
<a onClick={this.handleAccountClick} href={status.getIn(["account", "url"])} className='status__display-name'>
|
||||
<div className='status__avatar'>
|
||||
<Avatar account={status.get('account')} size={48} />
|
||||
<Avatar account={status.get("account")} size={48} />
|
||||
</div>
|
||||
|
||||
<DisplayName account={status.get('account')} />
|
||||
<DisplayName account={status.get("account")} />
|
||||
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<StatusContent status={status} />
|
||||
|
||||
{status.get('media_attachments').size > 0 && (
|
||||
{status.get("media_attachments").size > 0 && (
|
||||
<AttachmentList
|
||||
compact
|
||||
media={status.get('media_attachments')}
|
||||
media={status.get("media_attachments")}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage, injectIntl } from "react-intl";
|
||||
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { fetchFilters, createFilter, createFilterStatus } from 'flavours/glitch/actions/filters';
|
||||
import { fetchStatus } from 'flavours/glitch/actions/statuses';
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import AddedToFilter from 'flavours/glitch/features/filters/added_to_filter';
|
||||
import SelectFilter from 'flavours/glitch/features/filters/select_filter';
|
||||
import { fetchFilters, createFilter, createFilterStatus } from "flavours/glitch/actions/filters";
|
||||
import { fetchStatus } from "flavours/glitch/actions/statuses";
|
||||
import { IconButton } from "flavours/glitch/components/icon_button";
|
||||
import AddedToFilter from "flavours/glitch/features/filters/added_to_filter";
|
||||
import SelectFilter from "flavours/glitch/features/filters/select_filter";
|
||||
|
||||
const messages = defineMessages({
|
||||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||
close: { id: "lightbox.close", defaultMessage: "Close" },
|
||||
});
|
||||
|
||||
class FilterModal extends ImmutablePureComponent {
|
||||
@@ -25,7 +25,7 @@ class FilterModal extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
state = {
|
||||
step: 'select',
|
||||
step: "select",
|
||||
filterId: null,
|
||||
isSubmitting: false,
|
||||
isSubmitted: false,
|
||||
@@ -38,7 +38,7 @@ class FilterModal extends ImmutablePureComponent {
|
||||
handleSuccess = () => {
|
||||
const { dispatch, statusId } = this.props;
|
||||
dispatch(fetchStatus(statusId, true));
|
||||
this.setState({ isSubmitting: false, isSubmitted: true, step: 'submitted' });
|
||||
this.setState({ isSubmitting: false, isSubmitted: true, step: "submitted" });
|
||||
};
|
||||
|
||||
handleFail = () => {
|
||||
@@ -67,8 +67,8 @@ class FilterModal extends ImmutablePureComponent {
|
||||
|
||||
dispatch(createFilter({
|
||||
title,
|
||||
context: ['home', 'notifications', 'public', 'thread', 'account'],
|
||||
action: 'warn',
|
||||
context: ["home", "notifications", "public", "thread", "account"],
|
||||
action: "warn",
|
||||
}, this.handleNewFilterSuccess, this.handleFail));
|
||||
};
|
||||
|
||||
@@ -94,27 +94,27 @@ class FilterModal extends ImmutablePureComponent {
|
||||
let stepComponent;
|
||||
|
||||
switch(step) {
|
||||
case 'select':
|
||||
stepComponent = (
|
||||
<SelectFilter
|
||||
contextType={contextType}
|
||||
onSelectFilter={this.handleSelectFilter}
|
||||
onNewFilter={this.handleNewFilter}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case 'create':
|
||||
stepComponent = null;
|
||||
break;
|
||||
case 'submitted':
|
||||
stepComponent = (
|
||||
<AddedToFilter
|
||||
contextType={contextType}
|
||||
filterId={filterId}
|
||||
statusId={statusId}
|
||||
onClose={onClose}
|
||||
/>
|
||||
);
|
||||
case "select":
|
||||
stepComponent = (
|
||||
<SelectFilter
|
||||
contextType={contextType}
|
||||
onSelectFilter={this.handleSelectFilter}
|
||||
onNewFilter={this.handleNewFilter}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "create":
|
||||
stepComponent = null;
|
||||
break;
|
||||
case "submitted":
|
||||
stepComponent = (
|
||||
<AddedToFilter
|
||||
contextType={contextType}
|
||||
filterId={filterId}
|
||||
statusId={statusId}
|
||||
onClose={onClose}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,54 +1,53 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
||||
import { FormattedMessage, defineMessages, injectIntl } from "react-intl";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import classNames from "classnames";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import Textarea from 'react-textarea-autosize';
|
||||
import { length } from 'stringz';
|
||||
// eslint-disable-next-line import/extensions
|
||||
import tesseractWorkerPath from 'tesseract.js/dist/worker.min.js';
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import tesseractCorePath from 'tesseract.js-core/tesseract-core.wasm.js';
|
||||
import Textarea from "react-textarea-autosize";
|
||||
import { length } from "stringz";
|
||||
import tesseractWorkerPath from "tesseract.js/dist/worker.min.js";
|
||||
|
||||
import tesseractCorePath from "tesseract.js-core/tesseract-core.wasm.js";
|
||||
|
||||
import Button from 'flavours/glitch/components/button';
|
||||
import { GIFV } from 'flavours/glitch/components/gifv';
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import Audio from 'flavours/glitch/features/audio';
|
||||
import CharacterCounter from 'flavours/glitch/features/compose/components/character_counter';
|
||||
import UploadProgress from 'flavours/glitch/features/compose/components/upload_progress';
|
||||
import { Tesseract as fetchTesseract } from 'flavours/glitch/features/ui/util/async-components';
|
||||
import Video, { getPointerPosition } from 'flavours/glitch/features/video';
|
||||
import { me , maxMediaDescChars } from 'flavours/glitch/initial_state';
|
||||
import { assetHost } from 'flavours/glitch/utils/config';
|
||||
import Button from "flavours/glitch/components/button";
|
||||
import { GIFV } from "flavours/glitch/components/gifv";
|
||||
import { IconButton } from "flavours/glitch/components/icon_button";
|
||||
import Audio from "flavours/glitch/features/audio";
|
||||
import CharacterCounter from "flavours/glitch/features/compose/components/character_counter";
|
||||
import UploadProgress from "flavours/glitch/features/compose/components/upload_progress";
|
||||
import { Tesseract as fetchTesseract } from "flavours/glitch/features/ui/util/async-components";
|
||||
import Video, { getPointerPosition } from "flavours/glitch/features/video";
|
||||
import { me , maxMediaDescChars } from "flavours/glitch/initial_state";
|
||||
import { assetHost } from "flavours/glitch/utils/config";
|
||||
|
||||
import { changeUploadCompose, uploadThumbnail, onChangeMediaDescription, onChangeMediaFocus } from '../../../actions/compose';
|
||||
import { changeUploadCompose, uploadThumbnail, onChangeMediaDescription, onChangeMediaFocus } from "../../../actions/compose";
|
||||
|
||||
const messages = defineMessages({
|
||||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||
apply: { id: 'upload_modal.apply', defaultMessage: 'Apply' },
|
||||
applying: { id: 'upload_modal.applying', defaultMessage: 'Applying…' },
|
||||
placeholder: { id: 'upload_modal.description_placeholder', defaultMessage: 'A quick brown fox jumps over the lazy dog' },
|
||||
chooseImage: { id: 'upload_modal.choose_image', defaultMessage: 'Choose image' },
|
||||
discardMessage: { id: 'confirmations.discard_edit_media.message', defaultMessage: 'You have unsaved changes to the media description or preview, discard them anyway?' },
|
||||
discardConfirm: { id: 'confirmations.discard_edit_media.confirm', defaultMessage: 'Discard' },
|
||||
close: { id: "lightbox.close", defaultMessage: "Close" },
|
||||
apply: { id: "upload_modal.apply", defaultMessage: "Apply" },
|
||||
applying: { id: "upload_modal.applying", defaultMessage: "Applying…" },
|
||||
placeholder: { id: "upload_modal.description_placeholder", defaultMessage: "A quick brown fox jumps over the lazy dog" },
|
||||
chooseImage: { id: "upload_modal.choose_image", defaultMessage: "Choose image" },
|
||||
discardMessage: { id: "confirmations.discard_edit_media.message", defaultMessage: "You have unsaved changes to the media description or preview, discard them anyway?" },
|
||||
discardConfirm: { id: "confirmations.discard_edit_media.confirm", defaultMessage: "Discard" },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, { id }) => ({
|
||||
media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id),
|
||||
account: state.getIn(['accounts', me]),
|
||||
isUploadingThumbnail: state.getIn(['compose', 'isUploadingThumbnail']),
|
||||
description: state.getIn(['compose', 'media_modal', 'description']),
|
||||
lang: state.getIn(['compose', 'language']),
|
||||
focusX: state.getIn(['compose', 'media_modal', 'focusX']),
|
||||
focusY: state.getIn(['compose', 'media_modal', 'focusY']),
|
||||
dirty: state.getIn(['compose', 'media_modal', 'dirty']),
|
||||
is_changing_upload: state.getIn(['compose', 'is_changing_upload']),
|
||||
media: state.getIn(["compose", "media_attachments"]).find(item => item.get("id") === id),
|
||||
account: state.getIn(["accounts", me]),
|
||||
isUploadingThumbnail: state.getIn(["compose", "isUploadingThumbnail"]),
|
||||
description: state.getIn(["compose", "media_modal", "description"]),
|
||||
lang: state.getIn(["compose", "language"]),
|
||||
focusX: state.getIn(["compose", "media_modal", "focusX"]),
|
||||
focusY: state.getIn(["compose", "media_modal", "focusY"]),
|
||||
dirty: state.getIn(["compose", "media_modal", "dirty"]),
|
||||
is_changing_upload: state.getIn(["compose", "is_changing_upload"]),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, { id }) => ({
|
||||
@@ -71,9 +70,9 @@ const mapDispatchToProps = (dispatch, { id }) => ({
|
||||
|
||||
});
|
||||
|
||||
const removeExtraLineBreaks = str => str.replace(/\n\n/g, '******')
|
||||
.replace(/\n/g, ' ')
|
||||
.replace(/\*\*\*\*\*\*/g, '\n\n');
|
||||
const removeExtraLineBreaks = str => str.replace(/\n\n/g, "******")
|
||||
.replace(/\n/g, " ")
|
||||
.replace(/\*\*\*\*\*\*/g, "\n\n");
|
||||
|
||||
class ImageLoader extends PureComponent {
|
||||
|
||||
@@ -89,7 +88,7 @@ class ImageLoader extends PureComponent {
|
||||
|
||||
componentDidMount() {
|
||||
const image = new Image();
|
||||
image.addEventListener('load', () => this.setState({ loading: false }));
|
||||
image.addEventListener("load", () => this.setState({ loading: false }));
|
||||
image.src = this.props.src;
|
||||
}
|
||||
|
||||
@@ -124,25 +123,25 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
dirty: false,
|
||||
progress: 0,
|
||||
loading: true,
|
||||
ocrStatus: '',
|
||||
ocrStatus: "",
|
||||
};
|
||||
|
||||
componentWillUnmount () {
|
||||
document.removeEventListener('mousemove', this.handleMouseMove);
|
||||
document.removeEventListener('mouseup', this.handleMouseUp);
|
||||
document.removeEventListener("mousemove", this.handleMouseMove);
|
||||
document.removeEventListener("mouseup", this.handleMouseUp);
|
||||
}
|
||||
|
||||
handleMouseDown = e => {
|
||||
document.addEventListener('mousemove', this.handleMouseMove);
|
||||
document.addEventListener('mouseup', this.handleMouseUp);
|
||||
document.addEventListener("mousemove", this.handleMouseMove);
|
||||
document.addEventListener("mouseup", this.handleMouseUp);
|
||||
|
||||
this.updatePosition(e);
|
||||
this.setState({ dragging: true });
|
||||
};
|
||||
|
||||
handleTouchStart = e => {
|
||||
document.addEventListener('touchmove', this.handleMouseMove);
|
||||
document.addEventListener('touchend', this.handleTouchEnd);
|
||||
document.addEventListener("touchmove", this.handleMouseMove);
|
||||
document.addEventListener("touchend", this.handleTouchEnd);
|
||||
|
||||
this.updatePosition(e);
|
||||
this.setState({ dragging: true });
|
||||
@@ -153,15 +152,15 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
handleMouseUp = () => {
|
||||
document.removeEventListener('mousemove', this.handleMouseMove);
|
||||
document.removeEventListener('mouseup', this.handleMouseUp);
|
||||
document.removeEventListener("mousemove", this.handleMouseMove);
|
||||
document.removeEventListener("mouseup", this.handleMouseUp);
|
||||
|
||||
this.setState({ dragging: false });
|
||||
};
|
||||
|
||||
handleTouchEnd = () => {
|
||||
document.removeEventListener('touchmove', this.handleMouseMove);
|
||||
document.removeEventListener('touchend', this.handleTouchEnd);
|
||||
document.removeEventListener("touchmove", this.handleMouseMove);
|
||||
document.removeEventListener("touchend", this.handleTouchEnd);
|
||||
|
||||
this.setState({ dragging: false });
|
||||
};
|
||||
@@ -223,20 +222,20 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
corePath: tesseractCorePath,
|
||||
langPath: `${assetHost}/ocr/lang-data/`,
|
||||
logger: ({ status, progress }) => {
|
||||
if (status === 'recognizing text') {
|
||||
this.setState({ ocrStatus: 'detecting', progress });
|
||||
if (status === "recognizing text") {
|
||||
this.setState({ ocrStatus: "detecting", progress });
|
||||
} else {
|
||||
this.setState({ ocrStatus: 'preparing', progress });
|
||||
this.setState({ ocrStatus: "preparing", progress });
|
||||
}
|
||||
},
|
||||
cacheMethod: refreshCache ? 'refresh' : 'write',
|
||||
cacheMethod: refreshCache ? "refresh" : "write",
|
||||
});
|
||||
|
||||
let media_url = media.get('url');
|
||||
let media_url = media.get("url");
|
||||
|
||||
if (window.URL && URL.createObjectURL) {
|
||||
try {
|
||||
media_url = URL.createObjectURL(media.get('file'));
|
||||
media_url = URL.createObjectURL(media.get("file"));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
@@ -244,8 +243,8 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
|
||||
return (async () => {
|
||||
await worker.load();
|
||||
await worker.loadLanguage('eng');
|
||||
await worker.initialize('eng');
|
||||
await worker.loadLanguage("eng");
|
||||
await worker.initialize("eng");
|
||||
const { data: { text } } = await worker.recognize(media_url);
|
||||
this.setState({ detecting: false });
|
||||
this.props.onChangeDescription(removeExtraLineBreaks(text));
|
||||
@@ -283,10 +282,10 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
const x = (focusX / 2) + .5;
|
||||
const y = (focusY / -2) + .5;
|
||||
|
||||
const width = media.getIn(['meta', 'original', 'width']) || null;
|
||||
const height = media.getIn(['meta', 'original', 'height']) || null;
|
||||
const focals = ['image', 'gifv'].includes(media.get('type'));
|
||||
const thumbnailable = ['audio', 'video'].includes(media.get('type'));
|
||||
const width = media.getIn(["meta", "original", "width"]) || null;
|
||||
const height = media.getIn(["meta", "original", "height"]) || null;
|
||||
const focals = ["image", "gifv"].includes(media.get("type"));
|
||||
const thumbnailable = ["audio", "video"].includes(media.get("type"));
|
||||
|
||||
const previewRatio = 16/9;
|
||||
const previewWidth = 200;
|
||||
@@ -294,16 +293,16 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
|
||||
let descriptionLabel = null;
|
||||
|
||||
if (media.get('type') === 'audio') {
|
||||
if (media.get("type") === "audio") {
|
||||
descriptionLabel = <FormattedMessage id='upload_form.audio_description' defaultMessage='Describe for people who are hard of hearing' />;
|
||||
} else if (media.get('type') === 'video') {
|
||||
} else if (media.get("type") === "video") {
|
||||
descriptionLabel = <FormattedMessage id='upload_form.video_description' defaultMessage='Describe for people who are deaf, hard of hearing, blind or have low vision' />;
|
||||
} else {
|
||||
descriptionLabel = <FormattedMessage id='upload_form.description' defaultMessage='Describe for people who are blind or have low vision' />;
|
||||
}
|
||||
|
||||
let ocrMessage = '';
|
||||
if (ocrStatus === 'detecting') {
|
||||
let ocrMessage = "";
|
||||
if (ocrStatus === "detecting") {
|
||||
ocrMessage = <FormattedMessage id='upload_modal.analyzing_picture' defaultMessage='Analyzing picture…' />;
|
||||
} else {
|
||||
ocrMessage = <FormattedMessage id='upload_modal.preparing_ocr' defaultMessage='Preparing OCR…' />;
|
||||
@@ -324,10 +323,10 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
<>
|
||||
<label className='setting-text-label' htmlFor='upload-modal__thumbnail'><FormattedMessage id='upload_form.thumbnail' defaultMessage='Change thumbnail' /></label>
|
||||
|
||||
<Button disabled={isUploadingThumbnail || !media.get('unattached')} text={intl.formatMessage(messages.chooseImage)} onClick={this.handleFileInputClick} />
|
||||
<Button disabled={isUploadingThumbnail || !media.get("unattached")} text={intl.formatMessage(messages.chooseImage)} onClick={this.handleFileInputClick} />
|
||||
|
||||
<label>
|
||||
<span style={{ display: 'none' }}>{intl.formatMessage(messages.chooseImage)}</span>
|
||||
<span style={{ display: "none" }}>{intl.formatMessage(messages.chooseImage)}</span>
|
||||
|
||||
<input
|
||||
id='upload-modal__thumbnail'
|
||||
@@ -335,7 +334,7 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
type='file'
|
||||
accept='image/png,image/jpeg'
|
||||
onChange={this.handleThumbnailChange}
|
||||
style={{ display: 'none' }}
|
||||
style={{ display: "none" }}
|
||||
disabled={isUploadingThumbnail || is_changing_upload}
|
||||
/>
|
||||
</label>
|
||||
@@ -352,7 +351,7 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
<Textarea
|
||||
id='upload-modal__description'
|
||||
className='setting-text light'
|
||||
value={detecting ? '…' : description}
|
||||
value={detecting ? "…" : description}
|
||||
lang={lang}
|
||||
onChange={this.handleChange}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
@@ -366,8 +365,8 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
</div>
|
||||
|
||||
<div className='setting-text__toolbar'>
|
||||
<button disabled={detecting || media.get('type') !== 'image' || is_changing_upload} className='link-button' onClick={this.handleTextDetection}><FormattedMessage id='upload_modal.detect_text' defaultMessage='Detect text from picture' /></button>
|
||||
<CharacterCounter max={maxMediaDescChars} text={detecting ? '' : description} />
|
||||
<button disabled={detecting || media.get("type") !== "image" || is_changing_upload} className='link-button' onClick={this.handleTextDetection}><FormattedMessage id='upload_modal.detect_text' defaultMessage='Detect text from picture' /></button>
|
||||
<CharacterCounter max={maxMediaDescChars} text={detecting ? "" : description} />
|
||||
</div>
|
||||
|
||||
<Button disabled={!dirty || detecting || isUploadingThumbnail || length(description) > maxMediaDescChars || is_changing_upload} text={intl.formatMessage(is_changing_upload ? messages.applying : messages.apply)} onClick={this.handleSubmit} />
|
||||
@@ -375,13 +374,13 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
|
||||
<div className='focal-point-modal__content'>
|
||||
{focals && (
|
||||
<div className={classNames('focal-point', { dragging })} ref={this.setRef} onMouseDown={this.handleMouseDown} onTouchStart={this.handleTouchStart}>
|
||||
{media.get('type') === 'image' && <ImageLoader src={media.get('url')} width={width} height={height} alt='' />}
|
||||
{media.get('type') === 'gifv' && <GIFV src={media.get('url')} key={media.get('url')} width={width} height={height} />}
|
||||
<div className={classNames("focal-point", { dragging })} ref={this.setRef} onMouseDown={this.handleMouseDown} onTouchStart={this.handleTouchStart}>
|
||||
{media.get("type") === "image" && <ImageLoader src={media.get("url")} width={width} height={height} alt='' />}
|
||||
{media.get("type") === "gifv" && <GIFV src={media.get("url")} key={media.get("url")} width={width} height={height} />}
|
||||
|
||||
<div className='focal-point__preview'>
|
||||
<strong><FormattedMessage id='upload_modal.preview_label' defaultMessage='Preview ({ratio})' values={{ ratio: '16:9' }} /></strong>
|
||||
<div style={{ width: previewWidth, height: previewHeight, backgroundImage: `url(${media.get('preview_url')})`, backgroundSize: 'cover', backgroundPosition: `${x * 100}% ${y * 100}%` }} />
|
||||
<strong><FormattedMessage id='upload_modal.preview_label' defaultMessage='Preview ({ratio})' values={{ ratio: "16:9" }} /></strong>
|
||||
<div style={{ width: previewWidth, height: previewHeight, backgroundImage: `url(${media.get("preview_url")})`, backgroundSize: "cover", backgroundPosition: `${x * 100}% ${y * 100}%` }} />
|
||||
</div>
|
||||
|
||||
<div className='focal-point__reticle' style={{ top: `${y * 100}%`, left: `${x * 100}%` }} />
|
||||
@@ -389,27 +388,27 @@ class FocalPointModal extends ImmutablePureComponent {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{media.get('type') === 'video' && (
|
||||
{media.get("type") === "video" && (
|
||||
<Video
|
||||
preview={media.get('preview_url')}
|
||||
frameRate={media.getIn(['meta', 'original', 'frame_rate'])}
|
||||
blurhash={media.get('blurhash')}
|
||||
src={media.get('url')}
|
||||
preview={media.get("preview_url")}
|
||||
frameRate={media.getIn(["meta", "original", "frame_rate"])}
|
||||
blurhash={media.get("blurhash")}
|
||||
src={media.get("url")}
|
||||
detailed
|
||||
inline
|
||||
editable
|
||||
/>
|
||||
)}
|
||||
|
||||
{media.get('type') === 'audio' && (
|
||||
{media.get("type") === "audio" && (
|
||||
<Audio
|
||||
src={media.get('url')}
|
||||
duration={media.getIn(['meta', 'original', 'duration'], 0)}
|
||||
src={media.get("url")}
|
||||
duration={media.getIn(["meta", "original", "duration"], 0)}
|
||||
height={150}
|
||||
poster={media.get('preview_url') || account.get('avatar_static')}
|
||||
backgroundColor={media.getIn(['meta', 'colors', 'background'])}
|
||||
foregroundColor={media.getIn(['meta', 'colors', 'foreground'])}
|
||||
accentColor={media.getIn(['meta', 'colors', 'accent'])}
|
||||
poster={media.get("preview_url") || account.get("avatar_static")}
|
||||
backgroundColor={media.getIn(["meta", "colors", "background"])}
|
||||
foregroundColor={media.getIn(["meta", "colors", "foreground"])}
|
||||
accentColor={media.getIn(["meta", "colors", "accent"])}
|
||||
editable
|
||||
/>
|
||||
)}
|
||||
|
||||
+10
-10
@@ -1,21 +1,21 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { Component } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { Component } from "react";
|
||||
|
||||
import { injectIntl, defineMessages } from 'react-intl';
|
||||
import { injectIntl, defineMessages } from "react-intl";
|
||||
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
import { connect } from 'react-redux';
|
||||
import { List as ImmutableList } from "immutable";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { fetchFollowRequests } from 'flavours/glitch/actions/accounts';
|
||||
import { IconWithBadge } from 'flavours/glitch/components/icon_with_badge';
|
||||
import ColumnLink from 'flavours/glitch/features/ui/components/column_link';
|
||||
import { fetchFollowRequests } from "flavours/glitch/actions/accounts";
|
||||
import { IconWithBadge } from "flavours/glitch/components/icon_with_badge";
|
||||
import ColumnLink from "flavours/glitch/features/ui/components/column_link";
|
||||
|
||||
const messages = defineMessages({
|
||||
text: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
|
||||
text: { id: "navigation_bar.follow_requests", defaultMessage: "Follow requests" },
|
||||
});
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
count: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size,
|
||||
count: state.getIn(["user_lists", "follow_requests", "items"], ImmutableList()).size,
|
||||
});
|
||||
|
||||
class FollowRequestsColumnLink extends Component {
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
||||
import { FormattedMessage, defineMessages, injectIntl } from "react-intl";
|
||||
|
||||
import { Link, withRouter } from 'react-router-dom';
|
||||
import { Link, withRouter } from "react-router-dom";
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { fetchServer } from 'flavours/glitch/actions/server';
|
||||
import { Avatar } from 'flavours/glitch/components/avatar';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { WordmarkLogo, SymbolLogo } from 'flavours/glitch/components/logo';
|
||||
import Permalink from 'flavours/glitch/components/permalink';
|
||||
import { registrationsOpen, me, sso_redirect } from 'flavours/glitch/initial_state';
|
||||
import { openModal } from "flavours/glitch/actions/modal";
|
||||
import { fetchServer } from "flavours/glitch/actions/server";
|
||||
import { Avatar } from "flavours/glitch/components/avatar";
|
||||
import { Icon } from "flavours/glitch/components/icon";
|
||||
import { WordmarkLogo, SymbolLogo } from "flavours/glitch/components/logo";
|
||||
import Permalink from "flavours/glitch/components/permalink";
|
||||
import { registrationsOpen, me, sso_redirect } from "flavours/glitch/initial_state";
|
||||
|
||||
const Account = connect(state => ({
|
||||
account: state.getIn(['accounts', me]),
|
||||
account: state.getIn(["accounts", me]),
|
||||
}))(({ account }) => (
|
||||
<Permalink href={account.get('url')} to={`/@${account.get('acct')}`} title={account.get('acct')}>
|
||||
<Permalink href={account.get("url")} to={`/@${account.get("acct")}`} title={account.get("acct")}>
|
||||
<Avatar account={account} size={35} />
|
||||
</Permalink>
|
||||
));
|
||||
|
||||
const messages = defineMessages({
|
||||
search: { id: 'navigation_bar.search', defaultMessage: 'Search' },
|
||||
search: { id: "navigation_bar.search", defaultMessage: "Search" },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
signupUrl: state.getIn(['server', 'server', 'registrations', 'url'], null) || '/auth/sign_up',
|
||||
signupUrl: state.getIn(["server", "server", "registrations", "url"], null) || "/auth/sign_up",
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
openClosedRegistrationsModal() {
|
||||
dispatch(openModal({ modalType: 'CLOSED_REGISTRATIONS' }));
|
||||
dispatch(openModal({ modalType: "CLOSED_REGISTRATIONS" }));
|
||||
},
|
||||
dispatchServer() {
|
||||
dispatch(fetchServer());
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
class Header extends PureComponent {
|
||||
@@ -68,8 +68,8 @@ class Header extends PureComponent {
|
||||
if (signedIn) {
|
||||
content = (
|
||||
<>
|
||||
{location.pathname !== '/search' && <Link to='/search' className='button button-secondary' aria-label={intl.formatMessage(messages.search)}><Icon id='search' /></Link>}
|
||||
{location.pathname !== '/publish' && <Link to='/publish' className='button button-secondary'><FormattedMessage id='compose_form.publish_form' defaultMessage='New post' /></Link>}
|
||||
{location.pathname !== "/search" && <Link to='/search' className='button button-secondary' aria-label={intl.formatMessage(messages.search)}><Icon id='search' /></Link>}
|
||||
{location.pathname !== "/publish" && <Link to='/publish' className='button button-secondary'><FormattedMessage id='compose_form.publish_form' defaultMessage='New post' /></Link>}
|
||||
<Account />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import classNames from "classnames";
|
||||
|
||||
import { LoadingBar } from 'react-redux-loading-bar';
|
||||
import { LoadingBar } from "react-redux-loading-bar";
|
||||
|
||||
import ZoomableImage from './zoomable_image';
|
||||
import ZoomableImage from "./zoomable_image";
|
||||
|
||||
export default class ImageLoader extends PureComponent {
|
||||
|
||||
@@ -21,8 +21,8 @@ export default class ImageLoader extends PureComponent {
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
alt: '',
|
||||
lang: '',
|
||||
alt: "",
|
||||
lang: "",
|
||||
width: null,
|
||||
height: null,
|
||||
};
|
||||
@@ -40,7 +40,7 @@ export default class ImageLoader extends PureComponent {
|
||||
if (!this.canvas) {
|
||||
return null;
|
||||
}
|
||||
this._canvasContext = this._canvasContext || this.canvas.getContext('2d');
|
||||
this._canvasContext = this._canvasContext || this.canvas.getContext("2d");
|
||||
return this._canvasContext;
|
||||
}
|
||||
|
||||
@@ -75,8 +75,8 @@ export default class ImageLoader extends PureComponent {
|
||||
loadPreviewCanvas = ({ previewSrc, width, height }) => new Promise((resolve, reject) => {
|
||||
const image = new Image();
|
||||
const removeEventListeners = () => {
|
||||
image.removeEventListener('error', handleError);
|
||||
image.removeEventListener('load', handleLoad);
|
||||
image.removeEventListener("error", handleError);
|
||||
image.removeEventListener("load", handleLoad);
|
||||
};
|
||||
const handleError = () => {
|
||||
removeEventListeners();
|
||||
@@ -87,8 +87,8 @@ export default class ImageLoader extends PureComponent {
|
||||
this.canvasContext.drawImage(image, 0, 0, width, height);
|
||||
resolve();
|
||||
};
|
||||
image.addEventListener('error', handleError);
|
||||
image.addEventListener('load', handleLoad);
|
||||
image.addEventListener("error", handleError);
|
||||
image.addEventListener("load", handleLoad);
|
||||
image.src = previewSrc;
|
||||
this.removers.push(removeEventListeners);
|
||||
});
|
||||
@@ -101,8 +101,8 @@ export default class ImageLoader extends PureComponent {
|
||||
loadOriginalImage = ({ src }) => new Promise((resolve, reject) => {
|
||||
const image = new Image();
|
||||
const removeEventListeners = () => {
|
||||
image.removeEventListener('error', handleError);
|
||||
image.removeEventListener('load', handleLoad);
|
||||
image.removeEventListener("error", handleError);
|
||||
image.removeEventListener("load", handleLoad);
|
||||
};
|
||||
const handleError = () => {
|
||||
removeEventListeners();
|
||||
@@ -112,8 +112,8 @@ export default class ImageLoader extends PureComponent {
|
||||
removeEventListeners();
|
||||
resolve();
|
||||
};
|
||||
image.addEventListener('error', handleError);
|
||||
image.addEventListener('load', handleLoad);
|
||||
image.addEventListener("error", handleError);
|
||||
image.addEventListener("load", handleLoad);
|
||||
image.src = src;
|
||||
this.removers.push(removeEventListeners);
|
||||
});
|
||||
@@ -125,21 +125,23 @@ export default class ImageLoader extends PureComponent {
|
||||
|
||||
hasSize () {
|
||||
const { width, height } = this.props;
|
||||
return typeof width === 'number' && typeof height === 'number';
|
||||
return typeof width === "number" && typeof height === "number";
|
||||
}
|
||||
|
||||
setCanvasRef = c => {
|
||||
this.canvas = c;
|
||||
if (c) this.setState({ width: c.offsetWidth });
|
||||
if (c) {
|
||||
this.setState({ width: c.offsetWidth });
|
||||
}
|
||||
};
|
||||
|
||||
render () {
|
||||
const { alt, lang, src, width, height, onClick } = this.props;
|
||||
const { loading } = this.state;
|
||||
|
||||
const className = classNames('image-loader', {
|
||||
'image-loader--loading': loading,
|
||||
'image-loader--amorphous': !this.hasSize(),
|
||||
const className = classNames("image-loader", {
|
||||
"image-loader--loading": loading,
|
||||
"image-loader--amorphous": !this.hasSize(),
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { defineMessages, injectIntl } from "react-intl";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import classNames from "classnames";
|
||||
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import { IconButton } from "flavours/glitch/components/icon_button";
|
||||
|
||||
import ImageLoader from './image_loader';
|
||||
import ImageLoader from "./image_loader";
|
||||
|
||||
const messages = defineMessages({
|
||||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||
close: { id: "lightbox.close", defaultMessage: "Close" },
|
||||
});
|
||||
|
||||
class ImageModal extends PureComponent {
|
||||
@@ -36,8 +36,8 @@ class ImageModal extends PureComponent {
|
||||
const { intl, src, alt, onClose } = this.props;
|
||||
const { navigationHidden } = this.state;
|
||||
|
||||
const navigationClassName = classNames('media-modal__navigation', {
|
||||
'media-modal__navigation--hidden': navigationHidden,
|
||||
const navigationClassName = classNames("media-modal__navigation", {
|
||||
"media-modal__navigation--hidden": navigationHidden,
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
||||
import { FormattedMessage, defineMessages, injectIntl } from "react-intl";
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { version, source_url } from 'flavours/glitch/initial_state';
|
||||
import { logOut } from 'flavours/glitch/utils/log_out';
|
||||
import { openModal } from "flavours/glitch/actions/modal";
|
||||
import { version, source_url } from "flavours/glitch/initial_state";
|
||||
import { logOut } from "flavours/glitch/utils/log_out";
|
||||
|
||||
const messages = defineMessages({
|
||||
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
||||
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
|
||||
logoutMessage: { id: "confirmations.logout.message", defaultMessage: "Are you sure you want to log out?" },
|
||||
logoutConfirm: { id: "confirmations.logout.confirm", defaultMessage: "Log out" },
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||
onLogout () {
|
||||
dispatch(openModal({
|
||||
modalType: 'CONFIRM',
|
||||
modalType: "CONFIRM",
|
||||
modalProps: {
|
||||
message: intl.formatMessage(messages.logoutMessage),
|
||||
confirm: intl.formatMessage(messages.logoutConfirm),
|
||||
@@ -52,8 +52,8 @@ class LinkFooter extends PureComponent {
|
||||
};
|
||||
|
||||
render () {
|
||||
const DividingCircle = <span aria-hidden>{' · '}</span>;
|
||||
const software = 'Masto-FE (🦥 flavour)';
|
||||
const DividingCircle = <span aria-hidden>{" · "}</span>;
|
||||
const software = "Masto-FE (🦥 flavour)";
|
||||
return (
|
||||
<div className='link-footer'>
|
||||
<p>
|
||||
@@ -63,7 +63,7 @@ class LinkFooter extends PureComponent {
|
||||
{DividingCircle}
|
||||
<Link to='/keyboard-shortcuts'><FormattedMessage id='footer.keyboard_shortcuts' defaultMessage='Keyboard shortcuts' /></Link>
|
||||
{DividingCircle}
|
||||
<span class='version'>v{version}</span>
|
||||
<span className='version'>v{version}</span>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { withRouter } from "react-router-dom";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
import { connect } from "react-redux";
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
import { fetchLists } from 'flavours/glitch/actions/lists';
|
||||
import { fetchLists } from "flavours/glitch/actions/lists";
|
||||
|
||||
import ColumnLink from './column_link';
|
||||
import ColumnLink from "./column_link";
|
||||
|
||||
const getOrderedLists = createSelector([state => state.get('lists')], lists => {
|
||||
const getOrderedLists = createSelector([state => state.get("lists")], lists => {
|
||||
if (!lists) {
|
||||
return lists;
|
||||
}
|
||||
|
||||
return lists.toList().filter(item => !!item).sort((a, b) => a.get('title').localeCompare(b.get('title'))).take(4);
|
||||
return lists.toList().filter(item => !!item).sort((a, b) => a.get("title").localeCompare(b.get("title"))).take(4);
|
||||
});
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
@@ -47,7 +47,7 @@ class ListPanel extends ImmutablePureComponent {
|
||||
<hr />
|
||||
|
||||
{lists.map(list => (
|
||||
<ColumnLink icon='list-ul' key={list.get('id')} strict text={list.get('title')} to={`/lists/${list.get('id')}`} transparent />
|
||||
<ColumnLink icon='list-ul' key={list.get("id")} strict text={list.get("title")} to={`/lists/${list.get("id")}`} transparent />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { defineMessages, injectIntl } from "react-intl";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import classNames from "classnames";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
|
||||
import ReactSwipeableViews from 'react-swipeable-views';
|
||||
import ReactSwipeableViews from "react-swipeable-views";
|
||||
|
||||
import { getAverageFromBlurhash } from 'flavours/glitch/blurhash';
|
||||
import { GIFV } from 'flavours/glitch/components/gifv';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import Footer from 'flavours/glitch/features/picture_in_picture/components/footer';
|
||||
import Video from 'flavours/glitch/features/video';
|
||||
import { disableSwiping } from 'flavours/glitch/initial_state';
|
||||
import { getAverageFromBlurhash } from "flavours/glitch/blurhash";
|
||||
import { GIFV } from "flavours/glitch/components/gifv";
|
||||
import { Icon } from "flavours/glitch/components/icon";
|
||||
import { IconButton } from "flavours/glitch/components/icon_button";
|
||||
import Footer from "flavours/glitch/features/picture_in_picture/components/footer";
|
||||
import Video from "flavours/glitch/features/video";
|
||||
import { disableSwiping } from "flavours/glitch/initial_state";
|
||||
|
||||
import ImageLoader from './image_loader';
|
||||
import ImageLoader from "./image_loader";
|
||||
|
||||
const messages = defineMessages({
|
||||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||
previous: { id: 'lightbox.previous', defaultMessage: 'Previous' },
|
||||
next: { id: 'lightbox.next', defaultMessage: 'Next' },
|
||||
close: { id: "lightbox.close", defaultMessage: "Close" },
|
||||
previous: { id: "lightbox.previous", defaultMessage: "Previous" },
|
||||
next: { id: "lightbox.next", defaultMessage: "Next" },
|
||||
});
|
||||
|
||||
class MediaModal extends ImmutablePureComponent {
|
||||
@@ -75,7 +75,7 @@ class MediaModal extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
handleChangeIndex = (e) => {
|
||||
const index = Number(e.currentTarget.getAttribute('data-index'));
|
||||
const index = Number(e.currentTarget.getAttribute("data-index"));
|
||||
|
||||
this.setState({
|
||||
index: index % this.props.media.size,
|
||||
@@ -85,26 +85,26 @@ class MediaModal extends ImmutablePureComponent {
|
||||
|
||||
handleKeyDown = (e) => {
|
||||
switch(e.key) {
|
||||
case 'ArrowLeft':
|
||||
this.handlePrevClick();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
this.handleNextClick();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
break;
|
||||
case "ArrowLeft":
|
||||
this.handlePrevClick();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
break;
|
||||
case "ArrowRight":
|
||||
this.handleNextClick();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
window.addEventListener('keydown', this.handleKeyDown, false);
|
||||
window.addEventListener("keydown", this.handleKeyDown, false);
|
||||
this._sendBackgroundColor();
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
window.removeEventListener('keydown', this.handleKeyDown);
|
||||
window.removeEventListener("keydown", this.handleKeyDown);
|
||||
this.props.onChangeBackgroundColor(null);
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ class MediaModal extends ImmutablePureComponent {
|
||||
_sendBackgroundColor () {
|
||||
const { media, onChangeBackgroundColor } = this.props;
|
||||
const index = this.getIndex();
|
||||
const blurhash = media.getIn([index, 'blurhash']);
|
||||
const blurhash = media.getIn([index, "blurhash"]);
|
||||
|
||||
if (blurhash) {
|
||||
const backgroundColor = getAverageFromBlurhash(blurhash);
|
||||
@@ -145,35 +145,35 @@ class MediaModal extends ImmutablePureComponent {
|
||||
const rightNav = media.size > 1 && <button tabIndex={0} className='media-modal__nav media-modal__nav--right' onClick={this.handleNextClick} aria-label={intl.formatMessage(messages.next)}><Icon id='chevron-right' fixedWidth /></button>;
|
||||
|
||||
const content = media.map((image) => {
|
||||
const width = image.getIn(['meta', 'original', 'width']) || null;
|
||||
const height = image.getIn(['meta', 'original', 'height']) || null;
|
||||
const description = image.getIn(['translation', 'description']) || image.get('description');
|
||||
const width = image.getIn(["meta", "original", "width"]) || null;
|
||||
const height = image.getIn(["meta", "original", "height"]) || null;
|
||||
const description = image.getIn(["translation", "description"]) || image.get("description");
|
||||
|
||||
if (image.get('type') === 'image') {
|
||||
if (image.get("type") === "image") {
|
||||
return (
|
||||
<ImageLoader
|
||||
previewSrc={image.get('preview_url')}
|
||||
src={image.get('url')}
|
||||
previewSrc={image.get("preview_url")}
|
||||
src={image.get("url")}
|
||||
width={width}
|
||||
height={height}
|
||||
alt={description}
|
||||
lang={lang}
|
||||
key={image.get('url')}
|
||||
key={image.get("url")}
|
||||
onClick={this.toggleNavigation}
|
||||
zoomButtonHidden={this.state.zoomButtonHidden}
|
||||
/>
|
||||
);
|
||||
} else if (image.get('type') === 'video') {
|
||||
} else if (image.get("type") === "video") {
|
||||
const { currentTime, autoPlay, volume } = this.props;
|
||||
|
||||
return (
|
||||
<Video
|
||||
preview={image.get('preview_url')}
|
||||
blurhash={image.get('blurhash')}
|
||||
src={image.get('url')}
|
||||
width={image.get('width')}
|
||||
height={image.get('height')}
|
||||
frameRate={image.getIn(['meta', 'original', 'frame_rate'])}
|
||||
preview={image.get("preview_url")}
|
||||
blurhash={image.get("blurhash")}
|
||||
src={image.get("url")}
|
||||
width={image.get("width")}
|
||||
height={image.get("height")}
|
||||
frameRate={image.getIn(["meta", "original", "frame_rate"])}
|
||||
currentTime={currentTime || 0}
|
||||
autoPlay={autoPlay || false}
|
||||
volume={volume || 1}
|
||||
@@ -181,16 +181,16 @@ class MediaModal extends ImmutablePureComponent {
|
||||
detailed
|
||||
alt={description}
|
||||
lang={lang}
|
||||
key={image.get('url')}
|
||||
key={image.get("url")}
|
||||
/>
|
||||
);
|
||||
} else if (image.get('type') === 'gifv') {
|
||||
} else if (image.get("type") === "gifv") {
|
||||
return (
|
||||
<GIFV
|
||||
src={image.get('url')}
|
||||
src={image.get("url")}
|
||||
width={width}
|
||||
height={height}
|
||||
key={image.get('url')}
|
||||
key={image.get("url")}
|
||||
alt={description}
|
||||
lang={lang}
|
||||
onClick={this.toggleNavigation}
|
||||
@@ -206,23 +206,23 @@ class MediaModal extends ImmutablePureComponent {
|
||||
// browsers when it's address bar is visible.
|
||||
// https://developers.google.com/web/updates/2016/12/url-bar-resizing
|
||||
const swipeableViewsStyle = {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
};
|
||||
|
||||
const containerStyle = {
|
||||
alignItems: 'center', // center vertically
|
||||
alignItems: "center", // center vertically
|
||||
};
|
||||
|
||||
const navigationClassName = classNames('media-modal__navigation', {
|
||||
'media-modal__navigation--hidden': navigationHidden,
|
||||
const navigationClassName = classNames("media-modal__navigation", {
|
||||
"media-modal__navigation--hidden": navigationHidden,
|
||||
});
|
||||
|
||||
let pagination;
|
||||
|
||||
if (media.size > 1) {
|
||||
pagination = media.map((item, i) => (
|
||||
<button key={i} className={classNames('media-modal__page-dot', { active: i === index })} data-index={i} onClick={this.handleChangeIndex}>
|
||||
<button key={i} className={classNames("media-modal__page-dot", { active: i === index })} data-index={i} onClick={this.handleChangeIndex}>
|
||||
{i + 1}
|
||||
</button>
|
||||
));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator';
|
||||
import { LoadingIndicator } from "flavours/glitch/components/loading_indicator";
|
||||
|
||||
// Keep the markup in sync with <BundleModalError />
|
||||
// (make sure they have the same dimensions)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { Helmet } from "react-helmet";
|
||||
|
||||
import Base from 'flavours/glitch/components/modal_root';
|
||||
import Base from "flavours/glitch/components/modal_root";
|
||||
import {
|
||||
OnboardingModal,
|
||||
MuteModal,
|
||||
@@ -19,51 +19,51 @@ import {
|
||||
InteractionModal,
|
||||
SubscribedLanguagesModal,
|
||||
ClosedRegistrationsModal,
|
||||
} from 'flavours/glitch/features/ui/util/async-components';
|
||||
import { getScrollbarWidth } from 'flavours/glitch/utils/scrollbar';
|
||||
} from "flavours/glitch/features/ui/util/async-components";
|
||||
import { getScrollbarWidth } from "flavours/glitch/utils/scrollbar";
|
||||
|
||||
import BundleContainer from '../containers/bundle_container';
|
||||
import BundleContainer from "../containers/bundle_container";
|
||||
|
||||
import ActionsModal from './actions_modal';
|
||||
import AudioModal from './audio_modal';
|
||||
import BoostModal from './boost_modal';
|
||||
import BundleModalError from './bundle_modal_error';
|
||||
import ConfirmationModal from './confirmation_modal';
|
||||
import DeprecatedSettingsModal from './deprecated_settings_modal';
|
||||
import DoodleModal from './doodle_modal';
|
||||
import FavouriteModal from './favourite_modal';
|
||||
import FocalPointModal from './focal_point_modal';
|
||||
import ImageModal from './image_modal';
|
||||
import MediaModal from './media_modal';
|
||||
import ModalLoading from './modal_loading';
|
||||
import VideoModal from './video_modal';
|
||||
import ActionsModal from "./actions_modal";
|
||||
import AudioModal from "./audio_modal";
|
||||
import BoostModal from "./boost_modal";
|
||||
import BundleModalError from "./bundle_modal_error";
|
||||
import ConfirmationModal from "./confirmation_modal";
|
||||
import DeprecatedSettingsModal from "./deprecated_settings_modal";
|
||||
import DoodleModal from "./doodle_modal";
|
||||
import FavouriteModal from "./favourite_modal";
|
||||
import FocalPointModal from "./focal_point_modal";
|
||||
import ImageModal from "./image_modal";
|
||||
import MediaModal from "./media_modal";
|
||||
import ModalLoading from "./modal_loading";
|
||||
import VideoModal from "./video_modal";
|
||||
|
||||
export const MODAL_COMPONENTS = {
|
||||
'MEDIA': () => Promise.resolve({ default: MediaModal }),
|
||||
'ONBOARDING': OnboardingModal,
|
||||
'VIDEO': () => Promise.resolve({ default: VideoModal }),
|
||||
'AUDIO': () => Promise.resolve({ default: AudioModal }),
|
||||
'IMAGE': () => Promise.resolve({ default: ImageModal }),
|
||||
'BOOST': () => Promise.resolve({ default: BoostModal }),
|
||||
'FAVOURITE': () => Promise.resolve({ default: FavouriteModal }),
|
||||
'DOODLE': () => Promise.resolve({ default: DoodleModal }),
|
||||
'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }),
|
||||
'MUTE': MuteModal,
|
||||
'BLOCK': BlockModal,
|
||||
'REPORT': ReportModal,
|
||||
'SETTINGS': SettingsModal,
|
||||
'DEPRECATED_SETTINGS': () => Promise.resolve({ default: DeprecatedSettingsModal }),
|
||||
'ACTIONS': () => Promise.resolve({ default: ActionsModal }),
|
||||
'EMBED': EmbedModal,
|
||||
'LIST_EDITOR': ListEditor,
|
||||
'FOCAL_POINT': () => Promise.resolve({ default: FocalPointModal }),
|
||||
'LIST_ADDER': ListAdder,
|
||||
'PINNED_ACCOUNTS_EDITOR': PinnedAccountsEditor,
|
||||
'COMPARE_HISTORY': CompareHistoryModal,
|
||||
'FILTER': FilterModal,
|
||||
'SUBSCRIBED_LANGUAGES': SubscribedLanguagesModal,
|
||||
'INTERACTION': InteractionModal,
|
||||
'CLOSED_REGISTRATIONS': ClosedRegistrationsModal,
|
||||
"MEDIA": () => Promise.resolve({ default: MediaModal }),
|
||||
"ONBOARDING": OnboardingModal,
|
||||
"VIDEO": () => Promise.resolve({ default: VideoModal }),
|
||||
"AUDIO": () => Promise.resolve({ default: AudioModal }),
|
||||
"IMAGE": () => Promise.resolve({ default: ImageModal }),
|
||||
"BOOST": () => Promise.resolve({ default: BoostModal }),
|
||||
"FAVOURITE": () => Promise.resolve({ default: FavouriteModal }),
|
||||
"DOODLE": () => Promise.resolve({ default: DoodleModal }),
|
||||
"CONFIRM": () => Promise.resolve({ default: ConfirmationModal }),
|
||||
"MUTE": MuteModal,
|
||||
"BLOCK": BlockModal,
|
||||
"REPORT": ReportModal,
|
||||
"SETTINGS": SettingsModal,
|
||||
"DEPRECATED_SETTINGS": () => Promise.resolve({ default: DeprecatedSettingsModal }),
|
||||
"ACTIONS": () => Promise.resolve({ default: ActionsModal }),
|
||||
"EMBED": EmbedModal,
|
||||
"LIST_EDITOR": ListEditor,
|
||||
"FOCAL_POINT": () => Promise.resolve({ default: FocalPointModal }),
|
||||
"LIST_ADDER": ListAdder,
|
||||
"PINNED_ACCOUNTS_EDITOR": PinnedAccountsEditor,
|
||||
"COMPARE_HISTORY": CompareHistoryModal,
|
||||
"FILTER": FilterModal,
|
||||
"SUBSCRIBED_LANGUAGES": SubscribedLanguagesModal,
|
||||
"INTERACTION": InteractionModal,
|
||||
"CLOSED_REGISTRATIONS": ClosedRegistrationsModal,
|
||||
};
|
||||
|
||||
export default class ModalRoot extends PureComponent {
|
||||
@@ -81,11 +81,11 @@ export default class ModalRoot extends PureComponent {
|
||||
|
||||
componentDidUpdate () {
|
||||
if (this.props.type) {
|
||||
document.body.classList.add('with-modals--active');
|
||||
document.body.classList.add("with-modals--active");
|
||||
document.documentElement.style.marginRight = `${getScrollbarWidth()}px`;
|
||||
} else {
|
||||
document.body.classList.remove('with-modals--active');
|
||||
document.documentElement.style.marginRight = '0';
|
||||
document.body.classList.remove("with-modals--active");
|
||||
document.documentElement.style.marginRight = "0";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ export default class ModalRoot extends PureComponent {
|
||||
};
|
||||
|
||||
renderLoading = modalId => () => {
|
||||
return ['MEDIA', 'VIDEO', 'BOOST', 'FAVOURITE', 'DOODLE', 'CONFIRM', 'ACTIONS'].indexOf(modalId) === -1 ? <ModalLoading /> : null;
|
||||
return ["MEDIA", "VIDEO", "BOOST", "FAVOURITE", "DOODLE", "CONFIRM", "ACTIONS"].indexOf(modalId) === -1 ? <ModalLoading /> : null;
|
||||
};
|
||||
|
||||
renderError = (props) => {
|
||||
@@ -127,7 +127,7 @@ export default class ModalRoot extends PureComponent {
|
||||
<>
|
||||
<BundleContainer fetchComponent={MODAL_COMPONENTS[type]} loading={this.renderLoading(type)} error={this.renderError} renderDelay={200}>
|
||||
{(SpecificComponent) => {
|
||||
const ref = typeof SpecificComponent !== 'function' ? this.setModalRef : undefined;
|
||||
const ref = typeof SpecificComponent !== "function" ? this.setModalRef : undefined;
|
||||
return <SpecificComponent {...props} onChangeBackgroundColor={this.setBackgroundColor} onClose={this.handleClose} ref={ref} />;
|
||||
}}
|
||||
</BundleContainer>
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from "react-intl";
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import Toggle from 'react-toggle';
|
||||
import Toggle from "react-toggle";
|
||||
|
||||
import { muteAccount } from 'flavours/glitch/actions/accounts';
|
||||
import { closeModal } from 'flavours/glitch/actions/modal';
|
||||
import { toggleHideNotifications, changeMuteDuration } from 'flavours/glitch/actions/mutes';
|
||||
import Button from 'flavours/glitch/components/button';
|
||||
import { muteAccount } from "flavours/glitch/actions/accounts";
|
||||
import { closeModal } from "flavours/glitch/actions/modal";
|
||||
import { toggleHideNotifications, changeMuteDuration } from "flavours/glitch/actions/mutes";
|
||||
import Button from "flavours/glitch/components/button";
|
||||
|
||||
const messages = defineMessages({
|
||||
minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' },
|
||||
hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' },
|
||||
days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' },
|
||||
indefinite: { id: 'mute_modal.indefinite', defaultMessage: 'Indefinite' },
|
||||
minutes: { id: "intervals.full.minutes", defaultMessage: "{number, plural, one {# minute} other {# minutes}}" },
|
||||
hours: { id: "intervals.full.hours", defaultMessage: "{number, plural, one {# hour} other {# hours}}" },
|
||||
days: { id: "intervals.full.days", defaultMessage: "{number, plural, one {# day} other {# days}}" },
|
||||
indefinite: { id: "mute_modal.indefinite", defaultMessage: "Indefinite" },
|
||||
});
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
account: state.getIn(['mutes', 'new', 'account']),
|
||||
notifications: state.getIn(['mutes', 'new', 'notifications']),
|
||||
muteDuration: state.getIn(['mutes', 'new', 'duration']),
|
||||
account: state.getIn(["mutes", "new", "account"]),
|
||||
notifications: state.getIn(["mutes", "new", "notifications"]),
|
||||
muteDuration: state.getIn(["mutes", "new", "duration"]),
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
onConfirm(account, notifications, muteDuration) {
|
||||
dispatch(muteAccount(account.get('id'), notifications, muteDuration));
|
||||
dispatch(muteAccount(account.get("id"), notifications, muteDuration));
|
||||
},
|
||||
|
||||
onClose() {
|
||||
@@ -98,7 +98,7 @@ class MuteModal extends PureComponent {
|
||||
<FormattedMessage
|
||||
id='confirmations.mute.message'
|
||||
defaultMessage='Are you sure you want to mute {name}?'
|
||||
values={{ name: <strong>@{account.get('acct')}</strong> }}
|
||||
values={{ name: <strong>@{account.get("acct")}</strong> }}
|
||||
/>
|
||||
</p>
|
||||
<p className='mute-modal__explanation'>
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { Component } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { Component } from "react";
|
||||
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { defineMessages, injectIntl } from "react-intl";
|
||||
|
||||
import NavigationPortal from 'flavours/glitch/components/navigation_portal';
|
||||
import { timelinePreview, trendsEnabled } from 'flavours/glitch/initial_state';
|
||||
import { transientSingleColumn } from 'flavours/glitch/is_mobile';
|
||||
import NavigationPortal from "flavours/glitch/components/navigation_portal";
|
||||
import { timelinePreview, trendsEnabled } from "flavours/glitch/initial_state";
|
||||
import { transientSingleColumn } from "flavours/glitch/is_mobile";
|
||||
|
||||
import ColumnLink from './column_link';
|
||||
import DisabledAccountBanner from './disabled_account_banner';
|
||||
import FollowRequestsColumnLink from './follow_requests_column_link';
|
||||
import ListPanel from './list_panel';
|
||||
import NotificationsCounterIcon from './notifications_counter_icon';
|
||||
import SignInBanner from './sign_in_banner';
|
||||
import ColumnLink from "./column_link";
|
||||
import DisabledAccountBanner from "./disabled_account_banner";
|
||||
import FollowRequestsColumnLink from "./follow_requests_column_link";
|
||||
import ListPanel from "./list_panel";
|
||||
import NotificationsCounterIcon from "./notifications_counter_icon";
|
||||
import SignInBanner from "./sign_in_banner";
|
||||
|
||||
const messages = defineMessages({
|
||||
home: { id: 'tabs_bar.home', defaultMessage: 'Home' },
|
||||
notifications: { id: 'tabs_bar.notifications', defaultMessage: 'Notifications' },
|
||||
explore: { id: 'explore.title', defaultMessage: 'Explore' },
|
||||
firehose: { id: 'column.firehose', defaultMessage: 'Live feeds' },
|
||||
direct: { id: 'navigation_bar.direct', defaultMessage: 'Private mentions' },
|
||||
favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favorites' },
|
||||
bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' },
|
||||
lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' },
|
||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||
followsAndFollowers: { id: 'navigation_bar.follows_and_followers', defaultMessage: 'Follows and followers' },
|
||||
about: { id: 'navigation_bar.about', defaultMessage: 'About' },
|
||||
search: { id: 'navigation_bar.search', defaultMessage: 'Search' },
|
||||
advancedInterface: { id: 'navigation_bar.advanced_interface', defaultMessage: 'Open in advanced web interface' },
|
||||
openedInClassicInterface: { id: 'navigation_bar.opened_in_classic_interface', defaultMessage: 'Posts, accounts, and other specific pages are opened by default in the classic web interface.' },
|
||||
app_settings: { id: 'navigation_bar.app_settings', defaultMessage: 'App settings' },
|
||||
logout: { id: 'navigation_bar.logout', defaultMessage: 'Log out' },
|
||||
home: { id: "tabs_bar.home", defaultMessage: "Home" },
|
||||
notifications: { id: "tabs_bar.notifications", defaultMessage: "Notifications" },
|
||||
explore: { id: "explore.title", defaultMessage: "Explore" },
|
||||
firehose: { id: "column.firehose", defaultMessage: "Live feeds" },
|
||||
direct: { id: "navigation_bar.direct", defaultMessage: "Private mentions" },
|
||||
favourites: { id: "navigation_bar.favourites", defaultMessage: "Favorites" },
|
||||
bookmarks: { id: "navigation_bar.bookmarks", defaultMessage: "Bookmarks" },
|
||||
lists: { id: "navigation_bar.lists", defaultMessage: "Lists" },
|
||||
preferences: { id: "navigation_bar.preferences", defaultMessage: "Preferences" },
|
||||
followsAndFollowers: { id: "navigation_bar.follows_and_followers", defaultMessage: "Follows and followers" },
|
||||
about: { id: "navigation_bar.about", defaultMessage: "About" },
|
||||
search: { id: "navigation_bar.search", defaultMessage: "Search" },
|
||||
advancedInterface: { id: "navigation_bar.advanced_interface", defaultMessage: "Open in advanced web interface" },
|
||||
openedInClassicInterface: { id: "navigation_bar.opened_in_classic_interface", defaultMessage: "Posts, accounts, and other specific pages are opened by default in the classic web interface." },
|
||||
app_settings: { id: "navigation_bar.app_settings", defaultMessage: "App settings" },
|
||||
logout: { id: "navigation_bar.logout", defaultMessage: "Log out" },
|
||||
});
|
||||
|
||||
class NavigationPanel extends Component {
|
||||
@@ -47,7 +47,7 @@ class NavigationPanel extends Component {
|
||||
};
|
||||
|
||||
isFirehoseActive = (match, location) => {
|
||||
return match || location.pathname.startsWith('/public');
|
||||
return match || location.pathname.startsWith("/public");
|
||||
};
|
||||
|
||||
render() {
|
||||
@@ -58,10 +58,10 @@ class NavigationPanel extends Component {
|
||||
<div className='navigation-panel'>
|
||||
{transientSingleColumn && (
|
||||
<div className='navigation-panel__logo'>
|
||||
<div class='switch-to-advanced'>
|
||||
<div className='switch-to-advanced'>
|
||||
{intl.formatMessage(messages.openedInClassicInterface)}
|
||||
{" "}
|
||||
<a href={`/deck${location.pathname}`} class='switch-to-advanced__toggle'>
|
||||
<a href={`/deck${location.pathname}`} className='switch-to-advanced__toggle'>
|
||||
{intl.formatMessage(messages.advancedInterface)}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { IconWithBadge } from 'flavours/glitch/components/icon_with_badge';
|
||||
import { IconWithBadge } from "flavours/glitch/components/icon_with_badge";
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
count: state.getIn(['local_settings', 'notifications', 'tab_badge']) ? state.getIn(['notifications', 'unread']) : 0,
|
||||
id: 'bell',
|
||||
count: state.getIn(["local_settings", "notifications", "tab_badge"]) ? state.getIn(["notifications", "unread"]) : 0,
|
||||
id: "bell",
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(IconWithBadge);
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from "react-intl";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import classNames from "classnames";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { connect } from 'react-redux';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import ReactSwipeableViews from 'react-swipeable-views';
|
||||
import ReactSwipeableViews from "react-swipeable-views";
|
||||
|
||||
import Permalink from 'flavours/glitch/components/permalink';
|
||||
import ComposeForm from 'flavours/glitch/features/compose/components/compose_form';
|
||||
import DrawerAccount from 'flavours/glitch/features/compose/components/navigation_bar';
|
||||
import Search from 'flavours/glitch/features/compose/components/search';
|
||||
import { me, source_url } from 'flavours/glitch/initial_state';
|
||||
import Permalink from "flavours/glitch/components/permalink";
|
||||
import ComposeForm from "flavours/glitch/features/compose/components/compose_form";
|
||||
import DrawerAccount from "flavours/glitch/features/compose/components/navigation_bar";
|
||||
import Search from "flavours/glitch/features/compose/components/search";
|
||||
import { me, source_url } from "flavours/glitch/initial_state";
|
||||
|
||||
import ColumnHeader from './column_header';
|
||||
import ColumnHeader from "./column_header";
|
||||
|
||||
const noop = () => { };
|
||||
|
||||
const messages = defineMessages({
|
||||
home_title: { id: 'column.home', defaultMessage: 'Home' },
|
||||
notifications_title: { id: 'column.notifications', defaultMessage: 'Notifications' },
|
||||
local_title: { id: 'column.community', defaultMessage: 'Local timeline' },
|
||||
federated_title: { id: 'column.public', defaultMessage: 'Federated timeline' },
|
||||
home_title: { id: "column.home", defaultMessage: "Home" },
|
||||
notifications_title: { id: "column.notifications", defaultMessage: "Notifications" },
|
||||
local_title: { id: "column.community", defaultMessage: "Local timeline" },
|
||||
federated_title: { id: "column.public", defaultMessage: "Federated timeline" },
|
||||
});
|
||||
|
||||
const PageOne = ({ acct, domain }) => (
|
||||
<div className='onboarding-modal__page onboarding-modal__page-one'>
|
||||
<div style={{ flex: '0 0 auto' }}>
|
||||
<div style={{ flex: "0 0 auto" }}>
|
||||
<div className='onboarding-modal__page-one__elephant-friend' />
|
||||
</div>
|
||||
|
||||
@@ -132,12 +132,12 @@ PageFour.propTypes = {
|
||||
};
|
||||
|
||||
const PageSix = ({ admin, domain }) => {
|
||||
let adminSection = '';
|
||||
let adminSection = "";
|
||||
|
||||
if (admin) {
|
||||
adminSection = (
|
||||
<p>
|
||||
<FormattedMessage id='onboarding.page_six.admin' defaultMessage="Your instance's admin is {admin}." values={{ admin: <Permalink href={admin.get('url')} to={`/@${admin.get('acct')}`}>@{admin.get('acct')}</Permalink> }} />
|
||||
<FormattedMessage id='onboarding.page_six.admin' defaultMessage="Your instance's admin is {admin}." values={{ admin: <Permalink href={admin.get("url")} to={`/@${admin.get("acct")}`}>@{admin.get("acct")}</Permalink> }} />
|
||||
<br />
|
||||
<FormattedMessage id='onboarding.page_six.read_guidelines' defaultMessage="Please read {domain}'s {guidelines}!" values={{ domain, guidelines: <a href='/about/more' target='_blank'><FormattedMessage id='onboarding.page_six.guidelines' defaultMessage='community guidelines' /></a> }} />
|
||||
</p>
|
||||
@@ -154,13 +154,13 @@ const PageSix = ({ admin, domain }) => {
|
||||
defaultMessage='{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.'
|
||||
values={{
|
||||
domain,
|
||||
fork: <a href='https://en.wikipedia.org/wiki/Fork_(software_development)' target='_blank' rel='noopener'>fork</a>,
|
||||
Mastodon: <a href='https://github.com/mastodon/mastodon' target='_blank' rel='noopener'>Mastodon</a>,
|
||||
github: <a href={source_url} target='_blank' rel='noopener'>GitHub</a>,
|
||||
fork: <a href='https://en.wikipedia.org/wiki/Fork_(software_development)' target='_blank' rel="noopener noreferrer">fork</a>,
|
||||
Mastodon: <a href='https://github.com/mastodon/mastodon' target='_blank' rel="noopener noreferrer">Mastodon</a>,
|
||||
github: <a href={source_url} target='_blank' rel="noopener noreferrer">GitHub</a>,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<p><FormattedMessage id='onboarding.page_six.apps_available' defaultMessage='There are {apps} available for iOS, Android and other platforms.' values={{ domain, apps: <a href='https://joinmastodon.org/apps' target='_blank' rel='noopener'><FormattedMessage id='onboarding.page_six.various_app' defaultMessage='mobile apps' /></a> }} /></p>
|
||||
<p><FormattedMessage id='onboarding.page_six.apps_available' defaultMessage='There are {apps} available for iOS, Android and other platforms.' values={{ domain, apps: <a href='https://joinmastodon.org/apps' target='_blank' rel="noopener noreferrer"><FormattedMessage id='onboarding.page_six.various_app' defaultMessage='mobile apps' /></a> }} /></p>
|
||||
<p><em><FormattedMessage id='onboarding.page_six.appetoot' defaultMessage='Bon Appetoot!' /></em></p>
|
||||
</div>
|
||||
);
|
||||
@@ -172,9 +172,9 @@ PageSix.propTypes = {
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
myAccount: state.getIn(['accounts', me]),
|
||||
admin: state.getIn(['accounts', state.getIn(['meta', 'admin'])]),
|
||||
domain: state.getIn(['meta', 'domain']),
|
||||
myAccount: state.getIn(["accounts", me]),
|
||||
admin: state.getIn(["accounts", state.getIn(["meta", "admin"])]),
|
||||
domain: state.getIn(["meta", "domain"]),
|
||||
});
|
||||
|
||||
class OnboardingModal extends PureComponent {
|
||||
@@ -194,7 +194,7 @@ class OnboardingModal extends PureComponent {
|
||||
UNSAFE_componentWillMount() {
|
||||
const { myAccount, admin, domain, intl } = this.props;
|
||||
this.pages = [
|
||||
<PageOne key='1' acct={myAccount.get('acct')} domain={domain} />,
|
||||
<PageOne key='1' acct={myAccount.get("acct")} domain={domain} />,
|
||||
<PageTwo key='2' myAccount={myAccount} intl={intl} />,
|
||||
<PageThree key='3' myAccount={myAccount} intl={intl} />,
|
||||
<PageFour key='4' domain={domain} intl={intl} />,
|
||||
@@ -203,11 +203,11 @@ class OnboardingModal extends PureComponent {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('keyup', this.handleKeyUp);
|
||||
window.addEventListener("keyup", this.handleKeyUp);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.addEventListener('keyup', this.handleKeyUp);
|
||||
window.addEventListener("keyup", this.handleKeyUp);
|
||||
}
|
||||
|
||||
handleSkip = (e) => {
|
||||
@@ -216,7 +216,7 @@ class OnboardingModal extends PureComponent {
|
||||
};
|
||||
|
||||
handleDot = (e) => {
|
||||
const i = Number(e.currentTarget.getAttribute('data-index'));
|
||||
const i = Number(e.currentTarget.getAttribute("data-index"));
|
||||
e.preventDefault();
|
||||
this.setState({ currentIndex: i });
|
||||
};
|
||||
@@ -240,12 +240,12 @@ class OnboardingModal extends PureComponent {
|
||||
|
||||
handleKeyUp = ({ key }) => {
|
||||
switch (key) {
|
||||
case 'ArrowLeft':
|
||||
this.handlePrev();
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
this.handleNext();
|
||||
break;
|
||||
case "ArrowLeft":
|
||||
this.handlePrev();
|
||||
break;
|
||||
case "ArrowRight":
|
||||
this.handleNext();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -278,8 +278,8 @@ class OnboardingModal extends PureComponent {
|
||||
<div className='modal-root__modal onboarding-modal'>
|
||||
<ReactSwipeableViews index={currentIndex} onChangeIndex={this.handleSwipe} className='onboarding-modal__pager'>
|
||||
{pages.map((page, i) => {
|
||||
const className = classNames('onboarding-modal__page__wrapper', {
|
||||
'onboarding-modal__page__wrapper--active': i === currentIndex,
|
||||
const className = classNames("onboarding-modal__page__wrapper", {
|
||||
"onboarding-modal__page__wrapper--active": i === currentIndex,
|
||||
});
|
||||
return (
|
||||
<div key={i} className={className}>{page}</div>
|
||||
@@ -299,7 +299,7 @@ class OnboardingModal extends PureComponent {
|
||||
|
||||
<div className='onboarding-modal__dots'>
|
||||
{pages.map((_, i) => {
|
||||
const className = classNames('onboarding-modal__dot', {
|
||||
const className = classNames("onboarding-modal__dot", {
|
||||
active: i === currentIndex,
|
||||
});
|
||||
return (
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage, injectIntl } from "react-intl";
|
||||
|
||||
import { OrderedSet } from 'immutable';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
import { OrderedSet } from "immutable";
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { fetchRelationships } from 'flavours/glitch/actions/accounts';
|
||||
import { submitReport } from 'flavours/glitch/actions/reports';
|
||||
import { fetchServer } from 'flavours/glitch/actions/server';
|
||||
import { expandAccountTimeline } from 'flavours/glitch/actions/timelines';
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import Category from 'flavours/glitch/features/report/category';
|
||||
import Comment from 'flavours/glitch/features/report/comment';
|
||||
import Rules from 'flavours/glitch/features/report/rules';
|
||||
import Statuses from 'flavours/glitch/features/report/statuses';
|
||||
import Thanks from 'flavours/glitch/features/report/thanks';
|
||||
import { makeGetAccount } from 'flavours/glitch/selectors';
|
||||
import { fetchRelationships } from "flavours/glitch/actions/accounts";
|
||||
import { submitReport } from "flavours/glitch/actions/reports";
|
||||
import { fetchServer } from "flavours/glitch/actions/server";
|
||||
import { expandAccountTimeline } from "flavours/glitch/actions/timelines";
|
||||
import { IconButton } from "flavours/glitch/components/icon_button";
|
||||
import Category from "flavours/glitch/features/report/category";
|
||||
import Comment from "flavours/glitch/features/report/comment";
|
||||
import Rules from "flavours/glitch/features/report/rules";
|
||||
import Statuses from "flavours/glitch/features/report/statuses";
|
||||
import Thanks from "flavours/glitch/features/report/thanks";
|
||||
import { makeGetAccount } from "flavours/glitch/selectors";
|
||||
|
||||
const messages = defineMessages({
|
||||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||
close: { id: "lightbox.close", defaultMessage: "Close" },
|
||||
});
|
||||
|
||||
const makeMapStateToProps = () => {
|
||||
@@ -44,10 +44,10 @@ class ReportModal extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
state = {
|
||||
step: 'category',
|
||||
step: "category",
|
||||
selectedStatusIds: OrderedSet(this.props.statusId ? [this.props.statusId] : []),
|
||||
selectedDomains: OrderedSet(),
|
||||
comment: '',
|
||||
comment: "",
|
||||
category: null,
|
||||
selectedRuleIds: OrderedSet(),
|
||||
isSubmitting: false,
|
||||
@@ -72,7 +72,7 @@ class ReportModal extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
handleSuccess = () => {
|
||||
this.setState({ isSubmitting: false, isSubmitted: true, step: 'thanks' });
|
||||
this.setState({ isSubmitting: false, isSubmitted: true, step: "thanks" });
|
||||
};
|
||||
|
||||
handleFail = () => {
|
||||
@@ -148,71 +148,71 @@ class ReportModal extends ImmutablePureComponent {
|
||||
isSubmitted,
|
||||
} = this.state;
|
||||
|
||||
const domain = account.get('acct').split('@')[1];
|
||||
const domain = account.get("acct").split("@")[1];
|
||||
const isRemote = !!domain;
|
||||
|
||||
let stepComponent;
|
||||
|
||||
switch(step) {
|
||||
case 'category':
|
||||
stepComponent = (
|
||||
<Category
|
||||
onNextStep={this.handleNextStep}
|
||||
startedFrom={this.props.statusId ? 'status' : 'account'}
|
||||
category={category}
|
||||
onChangeCategory={this.handleChangeCategory}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case 'rules':
|
||||
stepComponent = (
|
||||
<Rules
|
||||
onNextStep={this.handleNextStep}
|
||||
selectedRuleIds={selectedRuleIds}
|
||||
onToggle={this.handleRuleToggle}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case 'statuses':
|
||||
stepComponent = (
|
||||
<Statuses
|
||||
onNextStep={this.handleNextStep}
|
||||
accountId={accountId}
|
||||
selectedStatusIds={selectedStatusIds}
|
||||
onToggle={this.handleStatusToggle}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case 'comment':
|
||||
stepComponent = (
|
||||
<Comment
|
||||
onSubmit={this.handleSubmit}
|
||||
isSubmitting={isSubmitting}
|
||||
isRemote={isRemote}
|
||||
comment={comment}
|
||||
domain={domain}
|
||||
onChangeComment={this.handleChangeComment}
|
||||
statusIds={selectedStatusIds}
|
||||
selectedDomains={selectedDomains}
|
||||
onToggleDomain={this.handleDomainToggle}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case 'thanks':
|
||||
stepComponent = (
|
||||
<Thanks
|
||||
submitted={isSubmitted}
|
||||
account={account}
|
||||
onClose={onClose}
|
||||
/>
|
||||
);
|
||||
case "category":
|
||||
stepComponent = (
|
||||
<Category
|
||||
onNextStep={this.handleNextStep}
|
||||
startedFrom={this.props.statusId ? "status" : "account"}
|
||||
category={category}
|
||||
onChangeCategory={this.handleChangeCategory}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "rules":
|
||||
stepComponent = (
|
||||
<Rules
|
||||
onNextStep={this.handleNextStep}
|
||||
selectedRuleIds={selectedRuleIds}
|
||||
onToggle={this.handleRuleToggle}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "statuses":
|
||||
stepComponent = (
|
||||
<Statuses
|
||||
onNextStep={this.handleNextStep}
|
||||
accountId={accountId}
|
||||
selectedStatusIds={selectedStatusIds}
|
||||
onToggle={this.handleStatusToggle}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "comment":
|
||||
stepComponent = (
|
||||
<Comment
|
||||
onSubmit={this.handleSubmit}
|
||||
isSubmitting={isSubmitting}
|
||||
isRemote={isRemote}
|
||||
comment={comment}
|
||||
domain={domain}
|
||||
onChangeComment={this.handleChangeComment}
|
||||
statusIds={selectedStatusIds}
|
||||
selectedDomains={selectedDomains}
|
||||
onToggleDomain={this.handleDomainToggle}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "thanks":
|
||||
stepComponent = (
|
||||
<Thanks
|
||||
submitted={isSubmitted}
|
||||
account={account}
|
||||
onClose={onClose}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='modal-root__modal report-dialog-modal'>
|
||||
<div className='report-modal__target'>
|
||||
<IconButton className='report-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={20} />
|
||||
<FormattedMessage id='report.target' defaultMessage='Report {target}' values={{ target: <strong>{account.get('acct')}</strong> }} />
|
||||
<FormattedMessage id='report.target' defaultMessage='Report {target}' values={{ target: <strong>{account.get("acct")}</strong> }} />
|
||||
</div>
|
||||
|
||||
<div className='report-dialog-modal__container'>
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useCallback } from "react";
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { registrationsOpen, sso_redirect } from 'flavours/glitch/initial_state';
|
||||
import { useAppDispatch, useAppSelector } from 'flavours/glitch/store';
|
||||
import { openModal } from "flavours/glitch/actions/modal";
|
||||
import { registrationsOpen, sso_redirect } from "flavours/glitch/initial_state";
|
||||
import { useAppDispatch, useAppSelector } from "flavours/glitch/store";
|
||||
|
||||
const SignInBanner = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const openClosedRegistrationsModal = useCallback(
|
||||
() => dispatch(openModal({ modalType: 'CLOSED_REGISTRATIONS' })),
|
||||
() => dispatch(openModal({ modalType: "CLOSED_REGISTRATIONS" })),
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
let signupButton;
|
||||
|
||||
const signupUrl = useAppSelector((state) => state.getIn(['server', 'server', 'registrations', 'url'], null) || '/auth/sign_up');
|
||||
const signupUrl = useAppSelector((state) => state.getIn(["server", "server", "registrations", "url"], null) || "/auth/sign_up");
|
||||
|
||||
if (sso_redirect) {
|
||||
return (
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import spring from 'react-motion/lib/spring';
|
||||
import spring from "react-motion/lib/spring";
|
||||
|
||||
import Motion from '../util/optional_motion';
|
||||
import Motion from "../util/optional_motion";
|
||||
|
||||
|
||||
|
||||
@@ -20,21 +20,21 @@ export default class UploadArea extends PureComponent {
|
||||
const keyCode = e.keyCode;
|
||||
if (this.props.active) {
|
||||
switch(keyCode) {
|
||||
case 27:
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.props.onClose();
|
||||
break;
|
||||
case 27:
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.props.onClose();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
window.addEventListener('keyup', this.handleKeyUp, false);
|
||||
window.addEventListener("keyup", this.handleKeyUp, false);
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
window.removeEventListener('keyup', this.handleKeyUp);
|
||||
window.removeEventListener("keyup", this.handleKeyUp);
|
||||
}
|
||||
|
||||
render () {
|
||||
@@ -43,7 +43,7 @@ export default class UploadArea extends PureComponent {
|
||||
return (
|
||||
<Motion defaultStyle={{ backgroundOpacity: 0, backgroundScale: 0.95 }} style={{ backgroundOpacity: spring(active ? 1 : 0, { stiffness: 150, damping: 15 }), backgroundScale: spring(active ? 1 : 0.95, { stiffness: 200, damping: 3 }) }}>
|
||||
{({ backgroundOpacity, backgroundScale }) =>
|
||||
(<div className='upload-area' style={{ visibility: active ? 'visible' : 'hidden', opacity: backgroundOpacity }}>
|
||||
(<div className='upload-area' style={{ visibility: active ? "visible" : "hidden", opacity: backgroundOpacity }}>
|
||||
<div className='upload-area__drop'>
|
||||
<div className='upload-area__background' style={{ transform: `scale(${backgroundScale})` }} />
|
||||
<div className='upload-area__content'><FormattedMessage id='upload_area.title' defaultMessage='Drag & drop to upload' /></div>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import ImmutablePureComponent from "react-immutable-pure-component";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { getAverageFromBlurhash } from 'flavours/glitch/blurhash';
|
||||
import Footer from 'flavours/glitch/features/picture_in_picture/components/footer';
|
||||
import Video from 'flavours/glitch/features/video';
|
||||
import { getAverageFromBlurhash } from "flavours/glitch/blurhash";
|
||||
import Footer from "flavours/glitch/features/picture_in_picture/components/footer";
|
||||
import Video from "flavours/glitch/features/video";
|
||||
|
||||
const mapStateToProps = (state, { statusId }) => ({
|
||||
status: state.getIn(['statuses', statusId]),
|
||||
status: state.getIn(["statuses", statusId]),
|
||||
});
|
||||
|
||||
class VideoModal extends ImmutablePureComponent {
|
||||
@@ -30,7 +30,7 @@ class VideoModal extends ImmutablePureComponent {
|
||||
componentDidMount () {
|
||||
const { media, onChangeBackgroundColor } = this.props;
|
||||
|
||||
const backgroundColor = getAverageFromBlurhash(media.get('blurhash'));
|
||||
const backgroundColor = getAverageFromBlurhash(media.get("blurhash"));
|
||||
|
||||
if (backgroundColor) {
|
||||
onChangeBackgroundColor(backgroundColor);
|
||||
@@ -40,17 +40,17 @@ class VideoModal extends ImmutablePureComponent {
|
||||
render () {
|
||||
const { media, status, onClose } = this.props;
|
||||
const options = this.props.options || {};
|
||||
const language = status.getIn(['translation', 'language']) || status.get('language');
|
||||
const description = media.getIn(['translation', 'description']) || media.get('description');
|
||||
const language = status.getIn(["translation", "language"]) || status.get("language");
|
||||
const description = media.getIn(["translation", "description"]) || media.get("description");
|
||||
|
||||
return (
|
||||
<div className='modal-root__modal video-modal'>
|
||||
<div className='video-modal__container'>
|
||||
<Video
|
||||
preview={media.get('preview_url')}
|
||||
frameRate={media.getIn(['meta', 'original', 'frame_rate'])}
|
||||
blurhash={media.get('blurhash')}
|
||||
src={media.get('url')}
|
||||
preview={media.get("preview_url")}
|
||||
frameRate={media.getIn(["meta", "original", "frame_rate"])}
|
||||
blurhash={media.get("blurhash")}
|
||||
src={media.get("url")}
|
||||
currentTime={options.startTime}
|
||||
autoPlay={options.autoPlay}
|
||||
volume={options.defaultVolume}
|
||||
@@ -63,7 +63,7 @@ class VideoModal extends ImmutablePureComponent {
|
||||
</div>
|
||||
|
||||
<div className='media-modal__overlay'>
|
||||
{status && <Footer statusId={status.get('id')} withOpenButton onClose={onClose} />}
|
||||
{status && <Footer statusId={status.get("id")} withOpenButton onClose={onClose} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent } from "react";
|
||||
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { defineMessages, injectIntl } from "react-intl";
|
||||
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import { IconButton } from "flavours/glitch/components/icon_button";
|
||||
|
||||
const messages = defineMessages({
|
||||
compress: { id: 'lightbox.compress', defaultMessage: 'Compress image view box' },
|
||||
expand: { id: 'lightbox.expand', defaultMessage: 'Expand image view box' },
|
||||
compress: { id: "lightbox.compress", defaultMessage: "Compress image view box" },
|
||||
expand: { id: "lightbox.expand", defaultMessage: "Expand image view box" },
|
||||
});
|
||||
|
||||
const MIN_SCALE = 1;
|
||||
@@ -38,21 +38,21 @@ const normalizeWheel = event => {
|
||||
pY = 0; // pixelX, pixelY
|
||||
|
||||
// Legacy
|
||||
if ('detail' in event) {
|
||||
if ("detail" in event) {
|
||||
sY = event.detail;
|
||||
}
|
||||
if ('wheelDelta' in event) {
|
||||
if ("wheelDelta" in event) {
|
||||
sY = -event.wheelDelta / 120;
|
||||
}
|
||||
if ('wheelDeltaY' in event) {
|
||||
if ("wheelDeltaY" in event) {
|
||||
sY = -event.wheelDeltaY / 120;
|
||||
}
|
||||
if ('wheelDeltaX' in event) {
|
||||
if ("wheelDeltaX" in event) {
|
||||
sX = -event.wheelDeltaX / 120;
|
||||
}
|
||||
|
||||
// side scrolling on FF with DOMMouseScroll
|
||||
if ('axis' in event && event.axis === event.HORIZONTAL_AXIS) {
|
||||
if ("axis" in event && event.axis === event.HORIZONTAL_AXIS) {
|
||||
sX = sY;
|
||||
sY = 0;
|
||||
}
|
||||
@@ -60,10 +60,10 @@ const normalizeWheel = event => {
|
||||
pX = sX * PIXEL_STEP;
|
||||
pY = sY * PIXEL_STEP;
|
||||
|
||||
if ('deltaY' in event) {
|
||||
if ("deltaY" in event) {
|
||||
pY = event.deltaY;
|
||||
}
|
||||
if ('deltaX' in event) {
|
||||
if ("deltaX" in event) {
|
||||
pX = event.deltaX;
|
||||
}
|
||||
|
||||
@@ -107,8 +107,8 @@ class ZoomableImage extends PureComponent {
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
alt: '',
|
||||
lang: '',
|
||||
alt: "",
|
||||
lang: "",
|
||||
width: null,
|
||||
height: null,
|
||||
};
|
||||
@@ -129,7 +129,7 @@ class ZoomableImage extends PureComponent {
|
||||
translateX: null,
|
||||
translateY: null,
|
||||
},
|
||||
zoomState: 'expand', // 'expand' 'compress'
|
||||
zoomState: "expand", // 'expand' 'compress'
|
||||
navigationHidden: false,
|
||||
dragPosition: { top: 0, left: 0, x: 0, y: 0 },
|
||||
dragged: false,
|
||||
@@ -145,27 +145,27 @@ class ZoomableImage extends PureComponent {
|
||||
|
||||
componentDidMount () {
|
||||
let handler = this.handleTouchStart;
|
||||
this.container.addEventListener('touchstart', handler);
|
||||
this.removers.push(() => this.container.removeEventListener('touchstart', handler));
|
||||
this.container.addEventListener("touchstart", handler);
|
||||
this.removers.push(() => this.container.removeEventListener("touchstart", handler));
|
||||
handler = this.handleTouchMove;
|
||||
// on Chrome 56+, touch event listeners will default to passive
|
||||
// https://www.chromestatus.com/features/5093566007214080
|
||||
this.container.addEventListener('touchmove', handler, { passive: false });
|
||||
this.removers.push(() => this.container.removeEventListener('touchend', handler));
|
||||
this.container.addEventListener("touchmove", handler, { passive: false });
|
||||
this.removers.push(() => this.container.removeEventListener("touchend", handler));
|
||||
|
||||
handler = this.mouseDownHandler;
|
||||
this.container.addEventListener('mousedown', handler);
|
||||
this.removers.push(() => this.container.removeEventListener('mousedown', handler));
|
||||
this.container.addEventListener("mousedown", handler);
|
||||
this.removers.push(() => this.container.removeEventListener("mousedown", handler));
|
||||
|
||||
handler = this.mouseWheelHandler;
|
||||
this.container.addEventListener('wheel', handler);
|
||||
this.removers.push(() => this.container.removeEventListener('wheel', handler));
|
||||
this.container.addEventListener("wheel", handler);
|
||||
this.removers.push(() => this.container.removeEventListener("wheel", handler));
|
||||
// Old Chrome
|
||||
this.container.addEventListener('mousewheel', handler);
|
||||
this.removers.push(() => this.container.removeEventListener('mousewheel', handler));
|
||||
this.container.addEventListener("mousewheel", handler);
|
||||
this.removers.push(() => this.container.removeEventListener("mousewheel", handler));
|
||||
// Old Firefox
|
||||
this.container.addEventListener('DOMMouseScroll', handler);
|
||||
this.removers.push(() => this.container.removeEventListener('DOMMouseScroll', handler));
|
||||
this.container.addEventListener("DOMMouseScroll", handler);
|
||||
this.removers.push(() => this.container.removeEventListener("DOMMouseScroll", handler));
|
||||
|
||||
this.initZoomMatrix();
|
||||
}
|
||||
@@ -175,10 +175,10 @@ class ZoomableImage extends PureComponent {
|
||||
}
|
||||
|
||||
componentDidUpdate () {
|
||||
this.setState({ zoomState: this.state.scale >= this.state.zoomMatrix.rate ? 'compress' : 'expand' });
|
||||
this.setState({ zoomState: this.state.scale >= this.state.zoomMatrix.rate ? "compress" : "expand" });
|
||||
|
||||
if (this.state.scale === MIN_SCALE) {
|
||||
this.container.style.removeProperty('cursor');
|
||||
this.container.style.removeProperty("cursor");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ class ZoomableImage extends PureComponent {
|
||||
|
||||
const event = normalizeWheel(e);
|
||||
|
||||
if (this.state.zoomMatrix.type === 'width') {
|
||||
if (this.state.zoomMatrix.type === "width") {
|
||||
// full width, scroll vertical
|
||||
this.container.scrollTop = Math.max(this.container.scrollTop + event.pixelY, this.state.lockScroll.y);
|
||||
} else {
|
||||
@@ -218,8 +218,8 @@ class ZoomableImage extends PureComponent {
|
||||
};
|
||||
|
||||
mouseDownHandler = e => {
|
||||
this.container.style.cursor = 'grabbing';
|
||||
this.container.style.userSelect = 'none';
|
||||
this.container.style.cursor = "grabbing";
|
||||
this.container.style.userSelect = "none";
|
||||
|
||||
this.setState({ dragPosition: {
|
||||
left: this.container.scrollLeft,
|
||||
@@ -229,8 +229,8 @@ class ZoomableImage extends PureComponent {
|
||||
y: e.clientY,
|
||||
} });
|
||||
|
||||
this.image.addEventListener('mousemove', this.mouseMoveHandler);
|
||||
this.image.addEventListener('mouseup', this.mouseUpHandler);
|
||||
this.image.addEventListener("mousemove", this.mouseMoveHandler);
|
||||
this.image.addEventListener("mouseup", this.mouseUpHandler);
|
||||
};
|
||||
|
||||
mouseMoveHandler = e => {
|
||||
@@ -244,15 +244,17 @@ class ZoomableImage extends PureComponent {
|
||||
};
|
||||
|
||||
mouseUpHandler = () => {
|
||||
this.container.style.cursor = 'grab';
|
||||
this.container.style.removeProperty('user-select');
|
||||
this.container.style.cursor = "grab";
|
||||
this.container.style.removeProperty("user-select");
|
||||
|
||||
this.image.removeEventListener('mousemove', this.mouseMoveHandler);
|
||||
this.image.removeEventListener('mouseup', this.mouseUpHandler);
|
||||
this.image.removeEventListener("mousemove", this.mouseMoveHandler);
|
||||
this.image.removeEventListener("mouseup", this.mouseUpHandler);
|
||||
};
|
||||
|
||||
handleTouchStart = e => {
|
||||
if (e.touches.length !== 2) return;
|
||||
if (e.touches.length !== 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.lastDistance = getDistance(...e.touches);
|
||||
};
|
||||
@@ -264,7 +266,9 @@ class ZoomableImage extends PureComponent {
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
if (e.touches.length !== 2) return;
|
||||
if (e.touches.length !== 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@@ -313,9 +317,13 @@ class ZoomableImage extends PureComponent {
|
||||
e.stopPropagation();
|
||||
const dragged = this.state.dragged;
|
||||
this.setState({ dragged: false });
|
||||
if (dragged) return;
|
||||
if (dragged) {
|
||||
return;
|
||||
}
|
||||
const handler = this.props.onClick;
|
||||
if (handler) handler();
|
||||
if (handler) {
|
||||
handler();
|
||||
}
|
||||
this.setState({ navigationHidden: !this.state.navigationHidden });
|
||||
};
|
||||
|
||||
@@ -329,13 +337,13 @@ class ZoomableImage extends PureComponent {
|
||||
const { offsetWidth, offsetHeight } = this.image;
|
||||
const clientHeightFixed = clientHeight - NAV_BAR_HEIGHT;
|
||||
|
||||
const type = width / height < clientWidth / clientHeightFixed ? 'width' : 'height';
|
||||
const fullScreen = type === 'width' ? width > clientWidth : height > clientHeightFixed;
|
||||
const rate = type === 'width' ? Math.min(clientWidth, width) / offsetWidth : Math.min(clientHeightFixed, height) / offsetHeight;
|
||||
const scrollTop = type === 'width' ? (clientHeight - offsetHeight) / 2 - NAV_BAR_HEIGHT : (clientHeightFixed - offsetHeight) / 2;
|
||||
const type = width / height < clientWidth / clientHeightFixed ? "width" : "height";
|
||||
const fullScreen = type === "width" ? width > clientWidth : height > clientHeightFixed;
|
||||
const rate = type === "width" ? Math.min(clientWidth, width) / offsetWidth : Math.min(clientHeightFixed, height) / offsetHeight;
|
||||
const scrollTop = type === "width" ? (clientHeight - offsetHeight) / 2 - NAV_BAR_HEIGHT : (clientHeightFixed - offsetHeight) / 2;
|
||||
const scrollLeft = (clientWidth - offsetWidth) / 2;
|
||||
const translateX = type === 'width' ? (width - offsetWidth) / (2 * rate) : 0;
|
||||
const translateY = type === 'height' ? (height - offsetHeight) / (2 * rate) : 0;
|
||||
const translateX = type === "width" ? (width - offsetWidth) / (2 * rate) : 0;
|
||||
const translateY = type === "height" ? (height - offsetHeight) / (2 * rate) : 0;
|
||||
|
||||
this.setState({
|
||||
zoomMatrix: {
|
||||
@@ -393,8 +401,8 @@ class ZoomableImage extends PureComponent {
|
||||
});
|
||||
}
|
||||
|
||||
this.container.style.cursor = 'grab';
|
||||
this.container.style.removeProperty('user-select');
|
||||
this.container.style.cursor = "grab";
|
||||
this.container.style.removeProperty("user-select");
|
||||
};
|
||||
|
||||
setContainerRef = c => {
|
||||
@@ -408,9 +416,9 @@ class ZoomableImage extends PureComponent {
|
||||
render () {
|
||||
const { alt, lang, src, width, height, intl } = this.props;
|
||||
const { scale, lockTranslate } = this.state;
|
||||
const overflow = scale === MIN_SCALE ? 'hidden' : 'scroll';
|
||||
const zoomButtonShouldHide = this.state.navigationHidden || this.props.zoomButtonHidden || this.state.zoomMatrix.rate <= MIN_SCALE ? 'media-modal__zoom-button--hidden' : '';
|
||||
const zoomButtonTitle = this.state.zoomState === 'compress' ? intl.formatMessage(messages.compress) : intl.formatMessage(messages.expand);
|
||||
const overflow = scale === MIN_SCALE ? "hidden" : "scroll";
|
||||
const zoomButtonShouldHide = this.state.navigationHidden || this.props.zoomButtonHidden || this.state.zoomMatrix.rate <= MIN_SCALE ? "media-modal__zoom-button--hidden" : "";
|
||||
const zoomButtonTitle = this.state.zoomState === "compress" ? intl.formatMessage(messages.compress) : intl.formatMessage(messages.expand);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -421,7 +429,7 @@ class ZoomableImage extends PureComponent {
|
||||
onClick={this.handleZoomClick}
|
||||
size={40}
|
||||
style={{
|
||||
fontSize: '30px', /* Fontawesome's fa-compress fa-expand is larger than fa-close */
|
||||
fontSize: "30px", /* Fontawesome's fa-compress fa-expand is larger than fa-close */
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
@@ -440,7 +448,7 @@ class ZoomableImage extends PureComponent {
|
||||
height={height}
|
||||
style={{
|
||||
transform: `scale(${scale}) translate(-${lockTranslate.x}px, -${lockTranslate.y}px)`,
|
||||
transformOrigin: '0 0',
|
||||
transformOrigin: "0 0",
|
||||
}}
|
||||
draggable={false}
|
||||
onClick={this.handleClick}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { fetchBundleRequest, fetchBundleSuccess, fetchBundleFail } from 'flavours/glitch/actions/bundles';
|
||||
import { fetchBundleRequest, fetchBundleSuccess, fetchBundleFail } from "flavours/glitch/actions/bundles";
|
||||
|
||||
import Bundle from '../components/bundle';
|
||||
import Bundle from "../components/bundle";
|
||||
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { defineMessages, injectIntl } from "react-intl";
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { logOut } from 'flavours/glitch/utils/log_out';
|
||||
import { openModal } from "flavours/glitch/actions/modal";
|
||||
import { logOut } from "flavours/glitch/utils/log_out";
|
||||
|
||||
import ColumnsArea from '../components/columns_area';
|
||||
import ColumnsArea from "../components/columns_area";
|
||||
|
||||
const messages = defineMessages({
|
||||
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
|
||||
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
|
||||
logoutMessage: { id: "confirmations.logout.message", defaultMessage: "Are you sure you want to log out?" },
|
||||
logoutConfirm: { id: "confirmations.logout.confirm", defaultMessage: "Log out" },
|
||||
});
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
columns: state.getIn(['settings', 'columns']),
|
||||
columns: state.getIn(["settings", "columns"]),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||
@@ -21,13 +21,13 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
dispatch(openModal({
|
||||
modalType: 'SETTINGS',
|
||||
modalType: "SETTINGS",
|
||||
modalProps: {},
|
||||
}));
|
||||
},
|
||||
onLogout () {
|
||||
dispatch(openModal({
|
||||
modalType: 'CONFIRM',
|
||||
modalType: "CONFIRM",
|
||||
modalProps: {
|
||||
message: intl.formatMessage(messages.logoutMessage),
|
||||
confirm: intl.formatMessage(messages.logoutConfirm),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import LoadingBar from 'react-redux-loading-bar';
|
||||
import LoadingBar from "react-redux-loading-bar";
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
loading: state.get('loadingBar')[ownProps.scope || 'default'],
|
||||
loading: state.get("loadingBar")[ownProps.scope || "default"],
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(LoadingBar.WrappedComponent);
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { openModal, closeModal } from 'flavours/glitch/actions/modal';
|
||||
import { openModal, closeModal } from "flavours/glitch/actions/modal";
|
||||
|
||||
import ModalRoot from '../components/modal_root';
|
||||
import ModalRoot from "../components/modal_root";
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
ignoreFocus: state.getIn(['modal', 'ignoreFocus']),
|
||||
type: state.getIn(['modal', 'stack', 0, 'modalType'], null),
|
||||
props: state.getIn(['modal', 'stack', 0, 'modalProps'], {}),
|
||||
ignoreFocus: state.getIn(["modal", "ignoreFocus"]),
|
||||
type: state.getIn(["modal", "stack", 0, "modalType"], null),
|
||||
props: state.getIn(["modal", "stack", 0, "modalProps"], {}),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
@@ -15,7 +15,7 @@ const mapDispatchToProps = dispatch => ({
|
||||
if (confirmationMessage) {
|
||||
dispatch(
|
||||
openModal({
|
||||
modalType: 'CONFIRM',
|
||||
modalType: "CONFIRM",
|
||||
modalProps: {
|
||||
message: confirmationMessage.message,
|
||||
confirm: confirmationMessage.confirm,
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { injectIntl } from 'react-intl';
|
||||
import { injectIntl } from "react-intl";
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { NotificationStack } from 'react-notification';
|
||||
import { NotificationStack } from "react-notification";
|
||||
|
||||
import { dismissAlert } from 'flavours/glitch/actions/alerts';
|
||||
import { getAlerts } from 'flavours/glitch/selectors';
|
||||
import { dismissAlert } from "flavours/glitch/actions/alerts";
|
||||
import { getAlerts } from "flavours/glitch/selectors";
|
||||
|
||||
const mapStateToProps = (state, { intl }) => {
|
||||
const notifications = getAlerts(state);
|
||||
|
||||
notifications.forEach(notification => ['title', 'message'].forEach(key => {
|
||||
notifications.forEach(notification => ["title", "message"].forEach(key => {
|
||||
const value = notification[key];
|
||||
|
||||
if (typeof value === 'object') {
|
||||
if (typeof value === "object") {
|
||||
notification[key] = intl.formatMessage(value, notification[`${key}_values`]);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { Map as ImmutableMap, List as ImmutableList } from "immutable";
|
||||
import { connect } from "react-redux";
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
import { debounce } from 'lodash';
|
||||
import { debounce } from "lodash";
|
||||
|
||||
import { scrollTopTimeline, loadPending } from 'flavours/glitch/actions/timelines';
|
||||
import StatusList from 'flavours/glitch/components/status_list';
|
||||
import { me } from 'flavours/glitch/initial_state';
|
||||
import { scrollTopTimeline, loadPending } from "flavours/glitch/actions/timelines";
|
||||
import StatusList from "flavours/glitch/components/status_list";
|
||||
import { me } from "flavours/glitch/initial_state";
|
||||
|
||||
const getRegex = createSelector([
|
||||
(state, { regex }) => regex,
|
||||
@@ -14,7 +14,7 @@ const getRegex = createSelector([
|
||||
let regex = null;
|
||||
|
||||
try {
|
||||
regex = rawRegex && new RegExp(rawRegex.trim(), 'i');
|
||||
regex = rawRegex && new RegExp(rawRegex.trim(), "i");
|
||||
} catch (e) {
|
||||
// Bad regex, don't affect filters
|
||||
}
|
||||
@@ -22,33 +22,37 @@ const getRegex = createSelector([
|
||||
});
|
||||
|
||||
const makeGetStatusIds = (pending = false) => createSelector([
|
||||
(state, { type }) => state.getIn(['settings', type], ImmutableMap()),
|
||||
(state, { type }) => state.getIn(['timelines', type, pending ? 'pendingItems' : 'items'], ImmutableList()),
|
||||
(state) => state.get('statuses'),
|
||||
(state, { type }) => state.getIn(["settings", type], ImmutableMap()),
|
||||
(state, { type }) => state.getIn(["timelines", type, pending ? "pendingItems" : "items"], ImmutableList()),
|
||||
(state) => state.get("statuses"),
|
||||
getRegex,
|
||||
], (columnSettings, statusIds, statuses, regex) => {
|
||||
return statusIds.filter(id => {
|
||||
if (id === null) return true;
|
||||
if (id === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const statusForId = statuses.get(id);
|
||||
let showStatus = true;
|
||||
|
||||
if (statusForId.get('account') === me) return true;
|
||||
|
||||
if (columnSettings.getIn(['shows', 'reblog']) === false) {
|
||||
showStatus = showStatus && statusForId.get('reblog') === null;
|
||||
if (statusForId.get("account") === me) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (columnSettings.getIn(['shows', 'reply']) === false) {
|
||||
showStatus = showStatus && (statusForId.get('in_reply_to_id') === null || statusForId.get('in_reply_to_account_id') === me);
|
||||
if (columnSettings.getIn(["shows", "reblog"]) === false) {
|
||||
showStatus = showStatus && statusForId.get("reblog") === null;
|
||||
}
|
||||
|
||||
if (columnSettings.getIn(['shows', 'direct']) === false) {
|
||||
showStatus = showStatus && statusForId.get('visibility') !== 'direct';
|
||||
if (columnSettings.getIn(["shows", "reply"]) === false) {
|
||||
showStatus = showStatus && (statusForId.get("in_reply_to_id") === null || statusForId.get("in_reply_to_account_id") === me);
|
||||
}
|
||||
|
||||
if (columnSettings.getIn(["shows", "direct"]) === false) {
|
||||
showStatus = showStatus && statusForId.get("visibility") !== "direct";
|
||||
}
|
||||
|
||||
if (showStatus && regex) {
|
||||
const searchIndex = statusForId.get('reblog') ? statuses.getIn([statusForId.get('reblog'), 'search_index']) : statusForId.get('search_index');
|
||||
const searchIndex = statusForId.get("reblog") ? statuses.getIn([statusForId.get("reblog"), "search_index"]) : statusForId.get("search_index");
|
||||
showStatus = !regex.test(searchIndex);
|
||||
}
|
||||
|
||||
@@ -62,10 +66,10 @@ const makeMapStateToProps = () => {
|
||||
|
||||
const mapStateToProps = (state, { timelineId, regex }) => ({
|
||||
statusIds: getStatusIds(state, { type: timelineId, regex }),
|
||||
lastId: state.getIn(['timelines', timelineId, 'items'])?.last(),
|
||||
isLoading: state.getIn(['timelines', timelineId, 'isLoading'], true),
|
||||
isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false),
|
||||
hasMore: state.getIn(['timelines', timelineId, 'hasMore']),
|
||||
lastId: state.getIn(["timelines", timelineId, "items"])?.last(),
|
||||
isLoading: state.getIn(["timelines", timelineId, "isLoading"], true),
|
||||
isPartial: state.getIn(["timelines", timelineId, "isPartial"], false),
|
||||
hasMore: state.getIn(["timelines", timelineId, "hasMore"]),
|
||||
numPending: getPendingStatusIds(state, { type: timelineId }).size,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PureComponent, Component } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { PureComponent, Component } from "react";
|
||||
|
||||
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage, injectIntl } from "react-intl";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { Redirect, Route, withRouter } from 'react-router-dom';
|
||||
import classNames from "classnames";
|
||||
import { Redirect, Route, withRouter } from "react-router-dom";
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import Favico from 'favico.js';
|
||||
import { debounce } from 'lodash';
|
||||
import { HotKeys } from 'react-hotkeys';
|
||||
import Favico from "favico.js";
|
||||
import { debounce } from "lodash";
|
||||
import { HotKeys } from "react-hotkeys";
|
||||
|
||||
import { changeLayout } from 'flavours/glitch/actions/app';
|
||||
import { uploadCompose, resetCompose, changeComposeSpoilerness } from 'flavours/glitch/actions/compose';
|
||||
import { clearHeight } from 'flavours/glitch/actions/height_cache';
|
||||
import { synchronouslySubmitMarkers, submitMarkers, fetchMarkers } from 'flavours/glitch/actions/markers';
|
||||
import { expandNotifications, notificationsSetVisibility } from 'flavours/glitch/actions/notifications';
|
||||
import { fetchServer } from 'flavours/glitch/actions/server';
|
||||
import { expandHomeTimeline } from 'flavours/glitch/actions/timelines';
|
||||
import PermaLink from 'flavours/glitch/components/permalink';
|
||||
import PictureInPicture from 'flavours/glitch/features/picture_in_picture';
|
||||
import { layoutFromWindow } from 'flavours/glitch/is_mobile';
|
||||
import { changeLayout } from "flavours/glitch/actions/app";
|
||||
import { uploadCompose, resetCompose, changeComposeSpoilerness } from "flavours/glitch/actions/compose";
|
||||
import { clearHeight } from "flavours/glitch/actions/height_cache";
|
||||
import { synchronouslySubmitMarkers, submitMarkers, fetchMarkers } from "flavours/glitch/actions/markers";
|
||||
import { expandNotifications, notificationsSetVisibility } from "flavours/glitch/actions/notifications";
|
||||
import { fetchServer } from "flavours/glitch/actions/server";
|
||||
import { expandHomeTimeline } from "flavours/glitch/actions/timelines";
|
||||
import PermaLink from "flavours/glitch/components/permalink";
|
||||
import PictureInPicture from "flavours/glitch/features/picture_in_picture";
|
||||
import { layoutFromWindow } from "flavours/glitch/is_mobile";
|
||||
|
||||
import initialState, { me, owner, singleUserMode, trendsEnabled, trendsAsLanding } from '../../initial_state';
|
||||
import initialState, { me, owner, singleUserMode, trendsEnabled, trendsAsLanding } from "../../initial_state";
|
||||
|
||||
import BundleColumnError from './components/bundle_column_error';
|
||||
import Header from './components/header';
|
||||
import UploadArea from './components/upload_area';
|
||||
import ColumnsAreaContainer from './containers/columns_area_container';
|
||||
import LoadingBarContainer from './containers/loading_bar_container';
|
||||
import ModalContainer from './containers/modal_container';
|
||||
import NotificationsContainer from './containers/notifications_container';
|
||||
import BundleColumnError from "./components/bundle_column_error";
|
||||
import Header from "./components/header";
|
||||
import UploadArea from "./components/upload_area";
|
||||
import ColumnsAreaContainer from "./containers/columns_area_container";
|
||||
import LoadingBarContainer from "./containers/loading_bar_container";
|
||||
import ModalContainer from "./containers/modal_container";
|
||||
import NotificationsContainer from "./containers/notifications_container";
|
||||
import {
|
||||
Compose,
|
||||
Status,
|
||||
@@ -64,65 +64,65 @@ import {
|
||||
FollowRecommendations,
|
||||
About,
|
||||
PrivacyPolicy,
|
||||
} from './util/async-components';
|
||||
import { WrappedSwitch, WrappedRoute } from './util/react_router_helpers';
|
||||
} from "./util/async-components";
|
||||
import { WrappedSwitch, WrappedRoute } from "./util/react_router_helpers";
|
||||
// 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";
|
||||
|
||||
const messages = defineMessages({
|
||||
beforeUnload: { id: 'ui.beforeunload', defaultMessage: 'Your draft will be lost if you leave Mastodon.' },
|
||||
beforeUnload: { id: "ui.beforeunload", defaultMessage: "Your draft will be lost if you leave Mastodon." },
|
||||
});
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
layout: state.getIn(['meta', 'layout']),
|
||||
hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0,
|
||||
hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0,
|
||||
canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4,
|
||||
layout_local_setting: state.getIn(['local_settings', 'layout']),
|
||||
isWide: state.getIn(['local_settings', 'stretch']),
|
||||
layout: state.getIn(["meta", "layout"]),
|
||||
hasComposingText: state.getIn(["compose", "text"]).trim().length !== 0,
|
||||
hasMediaAttachments: state.getIn(["compose", "media_attachments"]).size > 0,
|
||||
canUploadMore: !state.getIn(["compose", "media_attachments"]).some(x => ["audio", "video"].includes(x.get("type"))) && state.getIn(["compose", "media_attachments"]).size < 4,
|
||||
layout_local_setting: state.getIn(["local_settings", "layout"]),
|
||||
isWide: state.getIn(["local_settings", "stretch"]),
|
||||
dropdownMenuIsOpen: state.dropdownMenu.openId !== null,
|
||||
unreadNotifications: state.getIn(['notifications', 'unread']),
|
||||
showFaviconBadge: state.getIn(['local_settings', 'notifications', 'favicon_badge']),
|
||||
hicolorPrivacyIcons: state.getIn(['local_settings', 'hicolor_privacy_icons']),
|
||||
moved: state.getIn(['accounts', me, 'moved']) && state.getIn(['accounts', state.getIn(['accounts', me, 'moved'])]),
|
||||
unreadNotifications: state.getIn(["notifications", "unread"]),
|
||||
showFaviconBadge: state.getIn(["local_settings", "notifications", "favicon_badge"]),
|
||||
hicolorPrivacyIcons: state.getIn(["local_settings", "hicolor_privacy_icons"]),
|
||||
moved: state.getIn(["accounts", me, "moved"]) && state.getIn(["accounts", state.getIn(["accounts", me, "moved"])]),
|
||||
firstLaunch: false, // TODO: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION,
|
||||
username: state.getIn(['accounts', me, 'username']),
|
||||
username: state.getIn(["accounts", me, "username"]),
|
||||
});
|
||||
|
||||
const keyMap = {
|
||||
help: '?',
|
||||
new: 'n',
|
||||
search: 's',
|
||||
forceNew: 'option+n',
|
||||
toggleComposeSpoilers: 'option+x',
|
||||
focusColumn: ['1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
reply: 'r',
|
||||
favourite: 'f',
|
||||
boost: 'b',
|
||||
mention: 'm',
|
||||
open: ['enter', 'o'],
|
||||
openProfile: 'p',
|
||||
moveDown: ['down', 'j'],
|
||||
moveUp: ['up', 'k'],
|
||||
back: 'backspace',
|
||||
goToHome: 'g h',
|
||||
goToNotifications: 'g n',
|
||||
goToLocal: 'g l',
|
||||
goToFederated: 'g t',
|
||||
goToDirect: 'g d',
|
||||
goToStart: 'g s',
|
||||
goToFavourites: 'g f',
|
||||
goToPinned: 'g p',
|
||||
goToProfile: 'g u',
|
||||
goToBlocked: 'g b',
|
||||
goToMuted: 'g m',
|
||||
goToRequests: 'g r',
|
||||
toggleSpoiler: 'x',
|
||||
bookmark: 'd',
|
||||
toggleCollapse: 'shift+x',
|
||||
toggleSensitive: 'h',
|
||||
openMedia: 'e',
|
||||
help: "?",
|
||||
new: "n",
|
||||
search: "s",
|
||||
forceNew: "option+n",
|
||||
toggleComposeSpoilers: "option+x",
|
||||
focusColumn: ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
|
||||
reply: "r",
|
||||
favourite: "f",
|
||||
boost: "b",
|
||||
mention: "m",
|
||||
open: ["enter", "o"],
|
||||
openProfile: "p",
|
||||
moveDown: ["down", "j"],
|
||||
moveUp: ["up", "k"],
|
||||
back: "backspace",
|
||||
goToHome: "g h",
|
||||
goToNotifications: "g n",
|
||||
goToLocal: "g l",
|
||||
goToFederated: "g t",
|
||||
goToDirect: "g d",
|
||||
goToStart: "g s",
|
||||
goToFavourites: "g f",
|
||||
goToPinned: "g p",
|
||||
goToProfile: "g u",
|
||||
goToBlocked: "g b",
|
||||
goToMuted: "g m",
|
||||
goToRequests: "g r",
|
||||
toggleSpoiler: "x",
|
||||
bookmark: "d",
|
||||
toggleCollapse: "shift+x",
|
||||
toggleSensitive: "h",
|
||||
openMedia: "e",
|
||||
};
|
||||
|
||||
class SwitchingColumnsArea extends PureComponent {
|
||||
@@ -139,24 +139,24 @@ class SwitchingColumnsArea extends PureComponent {
|
||||
|
||||
UNSAFE_componentWillMount () {
|
||||
if (this.props.singleColumn) {
|
||||
document.body.classList.toggle('layout-single-column', true);
|
||||
document.body.classList.toggle('layout-multiple-columns', false);
|
||||
document.body.classList.toggle("layout-single-column", true);
|
||||
document.body.classList.toggle("layout-multiple-columns", false);
|
||||
} else {
|
||||
document.body.classList.toggle('layout-single-column', false);
|
||||
document.body.classList.toggle('layout-multiple-columns', true);
|
||||
document.body.classList.toggle("layout-single-column", false);
|
||||
document.body.classList.toggle("layout-multiple-columns", true);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
if (![this.props.location.pathname, '/'].includes(prevProps.location.pathname)) {
|
||||
if (this.node && this.node.handleChildrenContentChange === 'function') {
|
||||
if (![this.props.location.pathname, "/"].includes(prevProps.location.pathname)) {
|
||||
if (this.node && this.node.handleChildrenContentChange === "function") {
|
||||
this.node.handleChildrenContentChange();
|
||||
}
|
||||
}
|
||||
|
||||
if (prevProps.singleColumn !== this.props.singleColumn) {
|
||||
document.body.classList.toggle('layout-single-column', this.props.singleColumn);
|
||||
document.body.classList.toggle('layout-multiple-columns', !this.props.singleColumn);
|
||||
document.body.classList.toggle("layout-single-column", this.props.singleColumn);
|
||||
document.body.classList.toggle("layout-multiple-columns", !this.props.singleColumn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,20 +193,20 @@ class SwitchingColumnsArea extends PureComponent {
|
||||
{redirect}
|
||||
|
||||
{singleColumn ? <Redirect from='/getting-started' to='/home' exact /> : null}
|
||||
{pathName.startsWith('/deck/') ? <Redirect from={pathName} to={pathName.slice(5)} /> : null}
|
||||
{pathName.startsWith("/deck/") ? <Redirect from={pathName} to={pathName.slice(5)} /> : null}
|
||||
|
||||
<WrappedRoute path='/getting-started' component={GettingStarted} content={children} />
|
||||
<WrappedRoute path='/keyboard-shortcuts' component={KeyboardShortcuts} content={children} />
|
||||
<WrappedRoute path='/about' component={About} content={children} />
|
||||
<WrappedRoute path='/privacy-policy' component={PrivacyPolicy} content={children} />
|
||||
|
||||
<WrappedRoute path={['/home', '/timelines/home']} component={HomeTimeline} content={children} />
|
||||
<WrappedRoute path={["/home", "/timelines/home"]} component={HomeTimeline} content={children} />
|
||||
<Redirect from='/timelines/public' to='/public' exact />
|
||||
<Redirect from='/timelines/public/local' to='/public/local' exact />
|
||||
<WrappedRoute path='/public' exact component={Firehose} componentParams={{ feedType: 'public' }} content={children} />
|
||||
<WrappedRoute path='/public/local' exact component={Firehose} componentParams={{ feedType: 'community' }} content={children} />
|
||||
<WrappedRoute path='/public/remote' exact component={Firehose} componentParams={{ feedType: 'public:remote' }} content={children} />
|
||||
<WrappedRoute path={['/conversations', '/timelines/direct']} component={DirectTimeline} content={children} />
|
||||
<WrappedRoute path='/public' exact component={Firehose} componentParams={{ feedType: "public" }} content={children} />
|
||||
<WrappedRoute path='/public/local' exact component={Firehose} componentParams={{ feedType: "community" }} content={children} />
|
||||
<WrappedRoute path='/public/remote' exact component={Firehose} componentParams={{ feedType: "public:remote" }} content={children} />
|
||||
<WrappedRoute path={["/conversations", "/timelines/direct"]} component={DirectTimeline} content={children} />
|
||||
<WrappedRoute path='/tags/:id' component={HashtagTimeline} content={children} />
|
||||
<WrappedRoute path='/lists/:id' component={ListTimeline} content={children} />
|
||||
<WrappedRoute path='/notifications' component={Notifications} content={children} />
|
||||
@@ -217,15 +217,15 @@ class SwitchingColumnsArea extends PureComponent {
|
||||
|
||||
<WrappedRoute path='/start' component={FollowRecommendations} content={children} />
|
||||
<WrappedRoute path='/directory' component={Directory} content={children} />
|
||||
<WrappedRoute path={['/explore', '/search']} component={Explore} content={children} />
|
||||
<WrappedRoute path={['/publish', '/statuses/new']} component={Compose} content={children} />
|
||||
<WrappedRoute path={["/explore", "/search"]} component={Explore} content={children} />
|
||||
<WrappedRoute path={["/publish", "/statuses/new"]} component={Compose} content={children} />
|
||||
|
||||
<WrappedRoute path={['/@:acct', '/accounts/:id']} exact component={AccountTimeline} content={children} />
|
||||
<WrappedRoute path={["/@:acct", "/accounts/:id"]} exact component={AccountTimeline} content={children} />
|
||||
<WrappedRoute path='/@:acct/tagged/:tagged?' exact component={AccountTimeline} content={children} />
|
||||
<WrappedRoute path={['/@:acct/with_replies', '/accounts/:id/with_replies']} component={AccountTimeline} content={children} componentParams={{ withReplies: true }} />
|
||||
<WrappedRoute path={['/accounts/:id/followers', '/users/:acct/followers', '/@:acct/followers']} component={Followers} content={children} />
|
||||
<WrappedRoute path={['/accounts/:id/following', '/users/:acct/following', '/@:acct/following']} component={Following} content={children} />
|
||||
<WrappedRoute path={['/@:acct/media', '/accounts/:id/media']} component={AccountGallery} content={children} />
|
||||
<WrappedRoute path={["/@:acct/with_replies", "/accounts/:id/with_replies"]} component={AccountTimeline} content={children} componentParams={{ withReplies: true }} />
|
||||
<WrappedRoute path={["/accounts/:id/followers", "/users/:acct/followers", "/@:acct/followers"]} component={Followers} content={children} />
|
||||
<WrappedRoute path={["/accounts/:id/following", "/users/:acct/following", "/@:acct/following"]} component={Following} content={children} />
|
||||
<WrappedRoute path={["/@:acct/media", "/accounts/:id/media"]} component={AccountGallery} content={children} />
|
||||
<WrappedRoute path='/@:acct/:statusId' exact component={Status} content={children} />
|
||||
<WrappedRoute path='/@:acct/:statusId/reblogs' component={Reblogs} content={children} />
|
||||
<WrappedRoute path='/@:acct/:statusId/favourites' component={Favourites} content={children} />
|
||||
@@ -311,27 +311,31 @@ class UI extends Component {
|
||||
this.dragTargets.push(e.target);
|
||||
}
|
||||
|
||||
if (e.dataTransfer && e.dataTransfer.types.includes('Files') && this.props.canUploadMore && this.context.identity.signedIn) {
|
||||
if (e.dataTransfer && e.dataTransfer.types.includes("Files") && this.props.canUploadMore && this.context.identity.signedIn) {
|
||||
this.setState({ draggingOver: true });
|
||||
}
|
||||
};
|
||||
|
||||
handleDragOver = (e) => {
|
||||
if (this.dataTransferIsText(e.dataTransfer)) return false;
|
||||
if (this.dataTransferIsText(e.dataTransfer)) {
|
||||
return false;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
try {
|
||||
e.dataTransfer.dropEffect = 'copy';
|
||||
e.dataTransfer.dropEffect = "copy";
|
||||
} catch (err) {
|
||||
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
handleDrop = (e) => {
|
||||
if (this.dataTransferIsText(e.dataTransfer)) return;
|
||||
if (this.dataTransferIsText(e.dataTransfer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
@@ -357,7 +361,7 @@ class UI extends Component {
|
||||
};
|
||||
|
||||
dataTransferIsText = (dataTransfer) => {
|
||||
return (dataTransfer && Array.from(dataTransfer.types).filter((type) => type === 'text/plain').length === 1);
|
||||
return (dataTransfer && Array.from(dataTransfer.types).filter((type) => type === "text/plain").length === 1);
|
||||
};
|
||||
|
||||
closeUploadModal = () => {
|
||||
@@ -365,10 +369,10 @@ class UI extends Component {
|
||||
};
|
||||
|
||||
handleServiceWorkerPostMessage = ({ data }) => {
|
||||
if (data.type === 'navigate') {
|
||||
if (data.type === "navigate") {
|
||||
this.props.history.push(data.path);
|
||||
} else {
|
||||
console.warn('Unknown message type:', data.type);
|
||||
console.warn("Unknown message type:", data.type);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -400,24 +404,24 @@ class UI extends Component {
|
||||
componentDidMount () {
|
||||
const { signedIn } = this.context.identity;
|
||||
|
||||
window.addEventListener('beforeunload', this.handleBeforeUnload, false);
|
||||
window.addEventListener('resize', this.handleResize, { passive: true });
|
||||
window.addEventListener("beforeunload", this.handleBeforeUnload, false);
|
||||
window.addEventListener("resize", this.handleResize, { passive: true });
|
||||
|
||||
document.addEventListener('dragenter', this.handleDragEnter, false);
|
||||
document.addEventListener('dragover', this.handleDragOver, false);
|
||||
document.addEventListener('drop', this.handleDrop, false);
|
||||
document.addEventListener('dragleave', this.handleDragLeave, false);
|
||||
document.addEventListener('dragend', this.handleDragEnd, false);
|
||||
document.addEventListener("dragenter", this.handleDragEnter, false);
|
||||
document.addEventListener("dragover", this.handleDragOver, false);
|
||||
document.addEventListener("drop", this.handleDrop, false);
|
||||
document.addEventListener("dragleave", this.handleDragLeave, false);
|
||||
document.addEventListener("dragend", this.handleDragEnd, false);
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.addEventListener('message', this.handleServiceWorkerPostMessage);
|
||||
if ("serviceWorker" in navigator) {
|
||||
navigator.serviceWorker.addEventListener("message", this.handleServiceWorkerPostMessage);
|
||||
}
|
||||
|
||||
this.favicon = new Favico({ animation:'none' });
|
||||
this.favicon = new Favico({ animation:"none" });
|
||||
|
||||
// On first launch, redirect to the follow recommendations page
|
||||
if (signedIn && this.props.firstLaunch) {
|
||||
this.context.router.history.replace('/start');
|
||||
this.context.router.history.replace("/start");
|
||||
// TODO: this.props.dispatch(closeOnboarding());
|
||||
}
|
||||
|
||||
@@ -430,18 +434,18 @@ class UI extends Component {
|
||||
}
|
||||
|
||||
this.hotkeys.__mousetrap__.stopCallback = (e, element) => {
|
||||
return ['TEXTAREA', 'SELECT', 'INPUT'].includes(element.tagName);
|
||||
return ["TEXTAREA", "SELECT", "INPUT"].includes(element.tagName);
|
||||
};
|
||||
|
||||
if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support
|
||||
this.visibilityHiddenProp = 'hidden';
|
||||
this.visibilityChange = 'visibilitychange';
|
||||
} else if (typeof document.msHidden !== 'undefined') {
|
||||
this.visibilityHiddenProp = 'msHidden';
|
||||
this.visibilityChange = 'msvisibilitychange';
|
||||
} else if (typeof document.webkitHidden !== 'undefined') {
|
||||
this.visibilityHiddenProp = 'webkitHidden';
|
||||
this.visibilityChange = 'webkitvisibilitychange';
|
||||
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
|
||||
this.visibilityHiddenProp = "hidden";
|
||||
this.visibilityChange = "visibilitychange";
|
||||
} else if (typeof document.msHidden !== "undefined") {
|
||||
this.visibilityHiddenProp = "msHidden";
|
||||
this.visibilityChange = "msvisibilitychange";
|
||||
} else if (typeof document.webkitHidden !== "undefined") {
|
||||
this.visibilityHiddenProp = "webkitHidden";
|
||||
this.visibilityChange = "webkitvisibilitychange";
|
||||
}
|
||||
|
||||
if (this.visibilityChange !== undefined) {
|
||||
@@ -481,14 +485,14 @@ class UI extends Component {
|
||||
document.removeEventListener(this.visibilityChange, this.handleVisibilityChange);
|
||||
}
|
||||
|
||||
window.removeEventListener('beforeunload', this.handleBeforeUnload);
|
||||
window.removeEventListener('resize', this.handleResize);
|
||||
window.removeEventListener("beforeunload", this.handleBeforeUnload);
|
||||
window.removeEventListener("resize", this.handleResize);
|
||||
|
||||
document.removeEventListener('dragenter', this.handleDragEnter);
|
||||
document.removeEventListener('dragover', this.handleDragOver);
|
||||
document.removeEventListener('drop', this.handleDrop);
|
||||
document.removeEventListener('dragleave', this.handleDragLeave);
|
||||
document.removeEventListener('dragend', this.handleDragEnd);
|
||||
document.removeEventListener("dragenter", this.handleDragEnter);
|
||||
document.removeEventListener("dragover", this.handleDragOver);
|
||||
document.removeEventListener("drop", this.handleDrop);
|
||||
document.removeEventListener("dragleave", this.handleDragLeave);
|
||||
document.removeEventListener("dragend", this.handleDragEnd);
|
||||
}
|
||||
|
||||
setRef = c => {
|
||||
@@ -498,7 +502,7 @@ class UI extends Component {
|
||||
handleHotkeyNew = e => {
|
||||
e.preventDefault();
|
||||
|
||||
const element = this.node.querySelector('.compose-form__autosuggest-wrapper textarea');
|
||||
const element = this.node.querySelector(".compose-form__autosuggest-wrapper textarea");
|
||||
|
||||
if (element) {
|
||||
element.focus();
|
||||
@@ -508,7 +512,7 @@ class UI extends Component {
|
||||
handleHotkeySearch = e => {
|
||||
e.preventDefault();
|
||||
|
||||
const element = this.node.querySelector('.search__input');
|
||||
const element = this.node.querySelector(".search__input");
|
||||
|
||||
if (element) {
|
||||
element.focus();
|
||||
@@ -528,11 +532,13 @@ class UI extends Component {
|
||||
handleHotkeyFocusColumn = e => {
|
||||
const index = (e.key * 1) + 1; // First child is drawer, skip that
|
||||
const column = this.node.querySelector(`.column:nth-child(${index})`);
|
||||
if (!column) return;
|
||||
const container = column.querySelector('.scrollable');
|
||||
if (!column) {
|
||||
return;
|
||||
}
|
||||
const container = column.querySelector(".scrollable");
|
||||
|
||||
if (container) {
|
||||
const status = container.querySelector('.focusable');
|
||||
const status = container.querySelector(".focusable");
|
||||
|
||||
if (status) {
|
||||
if (container.scrollTop > status.offsetTop) {
|
||||
@@ -549,7 +555,7 @@ class UI extends Component {
|
||||
if (history.location?.state?.fromMastodon) {
|
||||
history.goBack();
|
||||
} else {
|
||||
history.push('/');
|
||||
history.push("/");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -558,43 +564,43 @@ class UI extends Component {
|
||||
};
|
||||
|
||||
handleHotkeyToggleHelp = () => {
|
||||
if (this.props.location.pathname === '/keyboard-shortcuts') {
|
||||
if (this.props.location.pathname === "/keyboard-shortcuts") {
|
||||
this.props.history.goBack();
|
||||
} else {
|
||||
this.props.history.push('/keyboard-shortcuts');
|
||||
this.props.history.push("/keyboard-shortcuts");
|
||||
}
|
||||
};
|
||||
|
||||
handleHotkeyGoToHome = () => {
|
||||
this.props.history.push('/home');
|
||||
this.props.history.push("/home");
|
||||
};
|
||||
|
||||
handleHotkeyGoToNotifications = () => {
|
||||
this.props.history.push('/notifications');
|
||||
this.props.history.push("/notifications");
|
||||
};
|
||||
|
||||
handleHotkeyGoToLocal = () => {
|
||||
this.props.history.push('/public/local');
|
||||
this.props.history.push("/public/local");
|
||||
};
|
||||
|
||||
handleHotkeyGoToFederated = () => {
|
||||
this.props.history.push('/public');
|
||||
this.props.history.push("/public");
|
||||
};
|
||||
|
||||
handleHotkeyGoToDirect = () => {
|
||||
this.props.history.push('/conversations');
|
||||
this.props.history.push("/conversations");
|
||||
};
|
||||
|
||||
handleHotkeyGoToStart = () => {
|
||||
this.props.history.push('/getting-started');
|
||||
this.props.history.push("/getting-started");
|
||||
};
|
||||
|
||||
handleHotkeyGoToFavourites = () => {
|
||||
this.props.history.push('/favourites');
|
||||
this.props.history.push("/favourites");
|
||||
};
|
||||
|
||||
handleHotkeyGoToPinned = () => {
|
||||
this.props.history.push('/pinned');
|
||||
this.props.history.push("/pinned");
|
||||
};
|
||||
|
||||
handleHotkeyGoToProfile = () => {
|
||||
@@ -602,15 +608,15 @@ class UI extends Component {
|
||||
};
|
||||
|
||||
handleHotkeyGoToBlocked = () => {
|
||||
this.props.history.push('/blocks');
|
||||
this.props.history.push("/blocks");
|
||||
};
|
||||
|
||||
handleHotkeyGoToMuted = () => {
|
||||
this.props.history.push('/mutes');
|
||||
this.props.history.push("/mutes");
|
||||
};
|
||||
|
||||
handleHotkeyGoToRequests = () => {
|
||||
this.props.history.push('/follow_requests');
|
||||
this.props.history.push("/follow_requests");
|
||||
};
|
||||
|
||||
render () {
|
||||
@@ -619,19 +625,19 @@ class UI extends Component {
|
||||
|
||||
const columnsClass = layout => {
|
||||
switch (layout) {
|
||||
case 'single':
|
||||
return 'single-column';
|
||||
case 'multiple':
|
||||
return 'multi-columns';
|
||||
default:
|
||||
return 'auto-columns';
|
||||
case "single":
|
||||
return "single-column";
|
||||
case "multiple":
|
||||
return "multi-columns";
|
||||
default:
|
||||
return "auto-columns";
|
||||
}
|
||||
};
|
||||
|
||||
const className = classNames('ui', columnsClass(layout), {
|
||||
'wide': isWide,
|
||||
'system-font': this.props.systemFontUi,
|
||||
'hicolor-privacy-icons': this.props.hicolorPrivacyIcons,
|
||||
const className = classNames("ui", columnsClass(layout), {
|
||||
"wide": isWide,
|
||||
"system-font": this.props.systemFontUi,
|
||||
"hicolor-privacy-icons": this.props.hicolorPrivacyIcons,
|
||||
});
|
||||
|
||||
const handlers = {
|
||||
@@ -658,14 +664,14 @@ class UI extends Component {
|
||||
|
||||
return (
|
||||
<HotKeys keyMap={keyMap} handlers={handlers} ref={this.setHotkeysRef} attach={window} focused>
|
||||
<div className={className} ref={this.setRef} style={{ pointerEvents: dropdownMenuIsOpen ? 'none' : null }}>
|
||||
<div className={className} ref={this.setRef} style={{ pointerEvents: dropdownMenuIsOpen ? "none" : null }}>
|
||||
{moved && (<div className='flash-message alert'>
|
||||
<FormattedMessage
|
||||
id='moved_to_warning'
|
||||
defaultMessage='This account is marked as moved to {moved_to_link}, and may thus not accept new follows.'
|
||||
values={{ moved_to_link: (
|
||||
<PermaLink href={moved.get('url')} to={`/@${moved.get('acct')}`}>
|
||||
@{moved.get('acct')}
|
||||
<PermaLink href={moved.get("url")} to={`/@${moved.get("acct")}`}>
|
||||
@{moved.get("acct")}
|
||||
</PermaLink>
|
||||
) }}
|
||||
/>
|
||||
@@ -673,11 +679,11 @@ class UI extends Component {
|
||||
|
||||
<Header />
|
||||
|
||||
<SwitchingColumnsArea location={location} singleColumn={layout === 'mobile' || layout === 'single-column'}>
|
||||
<SwitchingColumnsArea location={location} singleColumn={layout === "mobile" || layout === "single-column"}>
|
||||
{children}
|
||||
</SwitchingColumnsArea>
|
||||
|
||||
{layout !== 'mobile' && <PictureInPicture />}
|
||||
{layout !== "mobile" && <PictureInPicture />}
|
||||
<NotificationsContainer />
|
||||
<LoadingBarContainer className='loading-bar' />
|
||||
<ModalContainer />
|
||||
|
||||
@@ -1,207 +1,207 @@
|
||||
export function EmojiPicker () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/emoji_picker" */'flavours/glitch/features/emoji/emoji_picker');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/emoji_picker" */"flavours/glitch/features/emoji/emoji_picker");
|
||||
}
|
||||
|
||||
export function Compose () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/compose" */'flavours/glitch/features/compose');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/compose" */"flavours/glitch/features/compose");
|
||||
}
|
||||
|
||||
export function Notifications () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/notifications" */'flavours/glitch/features/notifications');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/notifications" */"flavours/glitch/features/notifications");
|
||||
}
|
||||
|
||||
export function HomeTimeline () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/home_timeline" */'flavours/glitch/features/home_timeline');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/home_timeline" */"flavours/glitch/features/home_timeline");
|
||||
}
|
||||
|
||||
export function PublicTimeline () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/public_timeline" */'flavours/glitch/features/public_timeline');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/public_timeline" */"flavours/glitch/features/public_timeline");
|
||||
}
|
||||
|
||||
export function CommunityTimeline () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/community_timeline" */'flavours/glitch/features/community_timeline');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/community_timeline" */"flavours/glitch/features/community_timeline");
|
||||
}
|
||||
|
||||
export function Firehose () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/firehose" */'../../firehose');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/firehose" */"../../firehose");
|
||||
}
|
||||
|
||||
export function HashtagTimeline () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/hashtag_timeline" */'flavours/glitch/features/hashtag_timeline');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/hashtag_timeline" */"flavours/glitch/features/hashtag_timeline");
|
||||
}
|
||||
|
||||
export function ListTimeline () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/list_timeline" */'flavours/glitch/features/list_timeline');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/list_timeline" */"flavours/glitch/features/list_timeline");
|
||||
}
|
||||
|
||||
export function Lists () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/lists" */'flavours/glitch/features/lists');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/lists" */"flavours/glitch/features/lists");
|
||||
}
|
||||
|
||||
export function ListEditor () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/list_editor" */'flavours/glitch/features/list_editor');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/list_editor" */"flavours/glitch/features/list_editor");
|
||||
}
|
||||
|
||||
export function PinnedAccountsEditor () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/pinned_accounts_editor" */'flavours/glitch/features/pinned_accounts_editor');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/pinned_accounts_editor" */"flavours/glitch/features/pinned_accounts_editor");
|
||||
}
|
||||
|
||||
export function DirectTimeline() {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/direct_timeline" */'flavours/glitch/features/direct_timeline');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/direct_timeline" */"flavours/glitch/features/direct_timeline");
|
||||
}
|
||||
|
||||
export function Status () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/status" */'flavours/glitch/features/status');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/status" */"flavours/glitch/features/status");
|
||||
}
|
||||
|
||||
export function GettingStarted () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/getting_started" */'flavours/glitch/features/getting_started');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/getting_started" */"flavours/glitch/features/getting_started");
|
||||
}
|
||||
|
||||
export function KeyboardShortcuts () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/keyboard_shortcuts" */'flavours/glitch/features/keyboard_shortcuts');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/keyboard_shortcuts" */"flavours/glitch/features/keyboard_shortcuts");
|
||||
}
|
||||
|
||||
export function PinnedStatuses () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/pinned_statuses" */'flavours/glitch/features/pinned_statuses');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/pinned_statuses" */"flavours/glitch/features/pinned_statuses");
|
||||
}
|
||||
|
||||
export function AccountTimeline () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/account_timeline" */'flavours/glitch/features/account_timeline');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/account_timeline" */"flavours/glitch/features/account_timeline");
|
||||
}
|
||||
|
||||
export function AccountGallery () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/account_gallery" */'flavours/glitch/features/account_gallery');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/account_gallery" */"flavours/glitch/features/account_gallery");
|
||||
}
|
||||
|
||||
export function Followers () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/followers" */'flavours/glitch/features/followers');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/followers" */"flavours/glitch/features/followers");
|
||||
}
|
||||
|
||||
export function Following () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/following" */'flavours/glitch/features/following');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/following" */"flavours/glitch/features/following");
|
||||
}
|
||||
|
||||
export function Reblogs () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/reblogs" */'flavours/glitch/features/reblogs');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/reblogs" */"flavours/glitch/features/reblogs");
|
||||
}
|
||||
|
||||
export function Favourites () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/favourites" */'flavours/glitch/features/favourites');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/favourites" */"flavours/glitch/features/favourites");
|
||||
}
|
||||
|
||||
export function FollowRequests () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/follow_requests" */'flavours/glitch/features/follow_requests');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/follow_requests" */"flavours/glitch/features/follow_requests");
|
||||
}
|
||||
|
||||
export function FavouritedStatuses () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/favourited_statuses" */'flavours/glitch/features/favourited_statuses');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/favourited_statuses" */"flavours/glitch/features/favourited_statuses");
|
||||
}
|
||||
|
||||
export function FollowedTags () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/followed_tags" */'flavours/glitch/features/followed_tags');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/followed_tags" */"flavours/glitch/features/followed_tags");
|
||||
}
|
||||
|
||||
export function BookmarkedStatuses () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/bookmarked_statuses" */'flavours/glitch/features/bookmarked_statuses');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/bookmarked_statuses" */"flavours/glitch/features/bookmarked_statuses");
|
||||
}
|
||||
|
||||
export function Blocks () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/blocks" */'flavours/glitch/features/blocks');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/blocks" */"flavours/glitch/features/blocks");
|
||||
}
|
||||
|
||||
export function DomainBlocks () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/domain_blocks" */'flavours/glitch/features/domain_blocks');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/domain_blocks" */"flavours/glitch/features/domain_blocks");
|
||||
}
|
||||
|
||||
export function Mutes () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/mutes" */'flavours/glitch/features/mutes');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/mutes" */"flavours/glitch/features/mutes");
|
||||
}
|
||||
|
||||
export function OnboardingModal () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/onboarding_modal" */'flavours/glitch/features/ui/components/onboarding_modal');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/onboarding_modal" */"flavours/glitch/features/ui/components/onboarding_modal");
|
||||
}
|
||||
|
||||
export function MuteModal () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/mute_modal" */'flavours/glitch/features/ui/components/mute_modal');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/mute_modal" */"flavours/glitch/features/ui/components/mute_modal");
|
||||
}
|
||||
|
||||
export function BlockModal () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/block_modal" */'flavours/glitch/features/ui/components/block_modal');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/block_modal" */"flavours/glitch/features/ui/components/block_modal");
|
||||
}
|
||||
|
||||
export function ReportModal () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/report_modal" */'flavours/glitch/features/ui/components/report_modal');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/report_modal" */"flavours/glitch/features/ui/components/report_modal");
|
||||
}
|
||||
|
||||
export function SettingsModal () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/settings_modal" */'flavours/glitch/features/local_settings');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/settings_modal" */"flavours/glitch/features/local_settings");
|
||||
}
|
||||
|
||||
export function MediaGallery () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/media_gallery" */'flavours/glitch/components/media_gallery');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/media_gallery" */"flavours/glitch/components/media_gallery");
|
||||
}
|
||||
|
||||
export function Video () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/video" */'flavours/glitch/features/video');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/video" */"flavours/glitch/features/video");
|
||||
}
|
||||
|
||||
export function Audio () {
|
||||
return import(/* webpackChunkName: "features/glitch/async/audio" */'flavours/glitch/features/audio');
|
||||
return import(/* webpackChunkName: "features/glitch/async/audio" */"flavours/glitch/features/audio");
|
||||
}
|
||||
|
||||
export function EmbedModal () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/embed_modal" */'flavours/glitch/features/ui/components/embed_modal');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/embed_modal" */"flavours/glitch/features/ui/components/embed_modal");
|
||||
}
|
||||
|
||||
export function GettingStartedMisc () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/getting_started_misc" */'flavours/glitch/features/getting_started_misc');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/getting_started_misc" */"flavours/glitch/features/getting_started_misc");
|
||||
}
|
||||
|
||||
export function ListAdder () {
|
||||
return import(/* webpackChunkName: "features/glitch/async/list_adder" */'flavours/glitch/features/list_adder');
|
||||
return import(/* webpackChunkName: "features/glitch/async/list_adder" */"flavours/glitch/features/list_adder");
|
||||
}
|
||||
|
||||
export function Tesseract () {
|
||||
return import(/*webpackChunkName: "tesseract" */'tesseract.js');
|
||||
return import(/*webpackChunkName: "tesseract" */"tesseract.js");
|
||||
}
|
||||
|
||||
export function Directory () {
|
||||
return import(/* webpackChunkName: "features/glitch/async/directory" */'flavours/glitch/features/directory');
|
||||
return import(/* webpackChunkName: "features/glitch/async/directory" */"flavours/glitch/features/directory");
|
||||
}
|
||||
|
||||
export function FollowRecommendations () {
|
||||
return import(/* webpackChunkName: "features/glitch/async/follow_recommendations" */'flavours/glitch/features/follow_recommendations');
|
||||
return import(/* webpackChunkName: "features/glitch/async/follow_recommendations" */"flavours/glitch/features/follow_recommendations");
|
||||
}
|
||||
|
||||
export function CompareHistoryModal () {
|
||||
return import(/*webpackChunkName: "flavours/glitch/async/compare_history_modal" */'flavours/glitch/features/ui/components/compare_history_modal');
|
||||
return import(/*webpackChunkName: "flavours/glitch/async/compare_history_modal" */"flavours/glitch/features/ui/components/compare_history_modal");
|
||||
}
|
||||
|
||||
export function FilterModal () {
|
||||
return import(/*webpackChunkName: "flavours/glitch/async/filter_modal" */'flavours/glitch/features/ui/components/filter_modal');
|
||||
return import(/*webpackChunkName: "flavours/glitch/async/filter_modal" */"flavours/glitch/features/ui/components/filter_modal");
|
||||
}
|
||||
|
||||
export function Explore () {
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/explore" */'flavours/glitch/features/explore');
|
||||
return import(/* webpackChunkName: "flavours/glitch/async/explore" */"flavours/glitch/features/explore");
|
||||
}
|
||||
|
||||
export function InteractionModal () {
|
||||
return import(/*webpackChunkName: "flavours/glitch/async/modals/interaction_modal" */'flavours/glitch/features/interaction_modal');
|
||||
return import(/*webpackChunkName: "flavours/glitch/async/modals/interaction_modal" */"flavours/glitch/features/interaction_modal");
|
||||
}
|
||||
|
||||
export function SubscribedLanguagesModal () {
|
||||
return import(/*webpackChunkName: "flavours/glitch/async/modals/subscribed_languages_modal" */'flavours/glitch/features/subscribed_languages_modal');
|
||||
return import(/*webpackChunkName: "flavours/glitch/async/modals/subscribed_languages_modal" */"flavours/glitch/features/subscribed_languages_modal");
|
||||
}
|
||||
|
||||
export function ClosedRegistrationsModal () {
|
||||
return import(/*webpackChunkName: "flavours/glitch/async/modals/closed_registrations_modal" */'flavours/glitch/features/closed_registrations_modal');
|
||||
return import(/*webpackChunkName: "flavours/glitch/async/modals/closed_registrations_modal" */"flavours/glitch/features/closed_registrations_modal");
|
||||
}
|
||||
|
||||
export function About () {
|
||||
return import(/*webpackChunkName: "features/glitch/async/about" */'flavours/glitch/features/about');
|
||||
return import(/*webpackChunkName: "features/glitch/async/about" */"flavours/glitch/features/about");
|
||||
}
|
||||
|
||||
export function PrivacyPolicy () {
|
||||
return import(/*webpackChunkName: "features/glitch/async/privacy_policy" */'flavours/glitch/features/privacy_policy');
|
||||
return import(/*webpackChunkName: "features/glitch/async/privacy_policy" */"flavours/glitch/features/privacy_policy");
|
||||
}
|
||||
|
||||
@@ -26,21 +26,21 @@ export const requestFullscreen = el => {
|
||||
};
|
||||
|
||||
export const attachFullscreenListener = (listener) => {
|
||||
if ('onfullscreenchange' in document) {
|
||||
document.addEventListener('fullscreenchange', listener);
|
||||
} else if ('onwebkitfullscreenchange' in document) {
|
||||
document.addEventListener('webkitfullscreenchange', listener);
|
||||
} else if ('onmozfullscreenchange' in document) {
|
||||
document.addEventListener('mozfullscreenchange', listener);
|
||||
if ("onfullscreenchange" in document) {
|
||||
document.addEventListener("fullscreenchange", listener);
|
||||
} else if ("onwebkitfullscreenchange" in document) {
|
||||
document.addEventListener("webkitfullscreenchange", listener);
|
||||
} else if ("onmozfullscreenchange" in document) {
|
||||
document.addEventListener("mozfullscreenchange", listener);
|
||||
}
|
||||
};
|
||||
|
||||
export const detachFullscreenListener = (listener) => {
|
||||
if ('onfullscreenchange' in document) {
|
||||
document.removeEventListener('fullscreenchange', listener);
|
||||
} else if ('onwebkitfullscreenchange' in document) {
|
||||
document.removeEventListener('webkitfullscreenchange', listener);
|
||||
} else if ('onmozfullscreenchange' in document) {
|
||||
document.removeEventListener('mozfullscreenchange', listener);
|
||||
if ("onfullscreenchange" in document) {
|
||||
document.removeEventListener("fullscreenchange", listener);
|
||||
} else if ("onwebkitfullscreenchange" in document) {
|
||||
document.removeEventListener("webkitfullscreenchange", listener);
|
||||
} else if ("onmozfullscreenchange" in document) {
|
||||
document.removeEventListener("mozfullscreenchange", listener);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
let hasBoundingRectBug;
|
||||
|
||||
function getRectFromEntry(entry) {
|
||||
if (typeof hasBoundingRectBug !== 'boolean') {
|
||||
if (typeof hasBoundingRectBug !== "boolean") {
|
||||
const boundingRect = entry.target.getBoundingClientRect();
|
||||
const observerRect = entry.boundingClientRect;
|
||||
hasBoundingRectBug = boundingRect.height !== observerRect.height ||
|
||||
|
||||
@@ -14,7 +14,7 @@ class IntersectionObserverWrapper {
|
||||
connect (options) {
|
||||
const onIntersection = (entries) => {
|
||||
entries.forEach(entry => {
|
||||
const id = entry.target.getAttribute('data-id');
|
||||
const id = entry.target.getAttribute("data-id");
|
||||
if (this.callbacks[id]) {
|
||||
this.callbacks[id](entry);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Motion from 'react-motion/lib/Motion';
|
||||
import Motion from "react-motion/lib/Motion";
|
||||
|
||||
import { reduceMotion } from 'flavours/glitch/initial_state';
|
||||
import { reduceMotion } from "flavours/glitch/initial_state";
|
||||
|
||||
import ReducedMotion from './reduced_motion';
|
||||
import ReducedMotion from "./reduced_motion";
|
||||
|
||||
export default reduceMotion ? ReducedMotion : Motion;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { Component, PureComponent, cloneElement, Children } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { Component, PureComponent, cloneElement, Children } from "react";
|
||||
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
import { Switch, Route } from "react-router-dom";
|
||||
|
||||
import StackTrace from 'stacktrace-js';
|
||||
import StackTrace from "stacktrace-js";
|
||||
|
||||
import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error';
|
||||
import ColumnLoading from 'flavours/glitch/features/ui/components/column_loading';
|
||||
import BundleContainer from 'flavours/glitch/features/ui/containers/bundle_container';
|
||||
import BundleColumnError from "flavours/glitch/features/ui/components/bundle_column_error";
|
||||
import ColumnLoading from "flavours/glitch/features/ui/components/column_loading";
|
||||
import BundleContainer from "flavours/glitch/features/ui/containers/bundle_container";
|
||||
|
||||
// Small wrapper to pass multiColumn to the route components
|
||||
export class WrappedSwitch extends PureComponent {
|
||||
@@ -19,7 +19,7 @@ export class WrappedSwitch extends PureComponent {
|
||||
const { multiColumn, children } = this.props;
|
||||
const { location } = this.context.router.route;
|
||||
|
||||
const decklessLocation = multiColumn && location.pathname.startsWith('/deck')
|
||||
const decklessLocation = multiColumn && location.pathname.startsWith("/deck")
|
||||
? {...location, pathname: location.pathname.slice(5)}
|
||||
: location;
|
||||
|
||||
@@ -61,12 +61,12 @@ export class WrappedRoute extends Component {
|
||||
|
||||
state = {
|
||||
hasError: false,
|
||||
stacktrace: '',
|
||||
stacktrace: "",
|
||||
};
|
||||
|
||||
componentDidCatch (error) {
|
||||
StackTrace.fromError(error).then(stackframes => {
|
||||
this.setState({ stacktrace: error.toString() + '\n' + stackframes.map(frame => frame.toString()).join('\n') });
|
||||
this.setState({ stacktrace: error.toString() + "\n" + stackframes.map(frame => frame.toString()).join("\n") });
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
// Like react-motion's Motion, but reduces all animations to cross-fades
|
||||
// for the benefit of users with motion sickness.
|
||||
import PropTypes from 'prop-types';
|
||||
import { Component } from 'react';
|
||||
import PropTypes from "prop-types";
|
||||
import { Component } from "react";
|
||||
|
||||
import Motion from 'react-motion/lib/Motion';
|
||||
import Motion from "react-motion/lib/Motion";
|
||||
|
||||
const stylesToKeep = ['opacity', 'backgroundOpacity'];
|
||||
const stylesToKeep = ["opacity", "backgroundOpacity"];
|
||||
|
||||
const extractValue = (value) => {
|
||||
// This is either an object with a "val" property or it's a number
|
||||
return (typeof value === 'object' && value && 'val' in value) ? value.val : value;
|
||||
return (typeof value === "object" && value && "val" in value) ? value.val : value;
|
||||
};
|
||||
|
||||
class ReducedMotion extends Component {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/API/Background_Tasks_API
|
||||
// for a good breakdown of the concepts behind this.
|
||||
|
||||
import Queue from 'tiny-queue';
|
||||
import Queue from "tiny-queue";
|
||||
|
||||
const taskQueue = new Queue();
|
||||
let runningRequestIdleCallback = false;
|
||||
|
||||
Reference in New Issue
Block a user