[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:
Zoë Bijl
2025-10-12 13:42:02 +02:00
committed by tobi
parent 75d7a62693
commit 1ff70886a1
975 changed files with 22196 additions and 21964 deletions
@@ -1,26 +1,26 @@
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 ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePropTypes from "react-immutable-proptypes";
import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
import DropdownMenuContainer from "../../../containers/dropdown_menu_container";
const messages = defineMessages({
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned posts' },
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favorites' },
lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' },
followed_tags: { id: 'navigation_bar.followed_tags', defaultMessage: 'Followed hashtags' },
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Blocked domains' },
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' },
edit_profile: { id: "account.edit_profile", defaultMessage: "Edit profile" },
pins: { id: "navigation_bar.pins", defaultMessage: "Pinned posts" },
preferences: { id: "navigation_bar.preferences", defaultMessage: "Preferences" },
follow_requests: { id: "navigation_bar.follow_requests", defaultMessage: "Follow requests" },
favourites: { id: "navigation_bar.favourites", defaultMessage: "Favorites" },
lists: { id: "navigation_bar.lists", defaultMessage: "Lists" },
followed_tags: { id: "navigation_bar.followed_tags", defaultMessage: "Followed hashtags" },
blocks: { id: "navigation_bar.blocks", defaultMessage: "Blocked users" },
domain_blocks: { id: "navigation_bar.domain_blocks", defaultMessage: "Blocked domains" },
mutes: { id: "navigation_bar.mutes", defaultMessage: "Muted users" },
filters: { id: "navigation_bar.filters", defaultMessage: "Muted words" },
logout: { id: "navigation_bar.logout", defaultMessage: "Logout" },
bookmarks: { id: "navigation_bar.bookmarks", defaultMessage: "Bookmarks" },
});
class ActionBar extends PureComponent {
@@ -40,20 +40,20 @@ class ActionBar extends PureComponent {
let menu = [];
menu.push({ text: intl.formatMessage(messages.edit_profile), href: '/settings/profile' });
menu.push({ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' });
menu.push({ text: intl.formatMessage(messages.pins), to: '/pinned' });
menu.push({ text: intl.formatMessage(messages.edit_profile), href: "/settings/profile" });
menu.push({ text: intl.formatMessage(messages.preferences), href: "/settings/preferences" });
menu.push({ text: intl.formatMessage(messages.pins), to: "/pinned" });
menu.push(null);
menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' });
menu.push({ text: intl.formatMessage(messages.favourites), to: '/favourites' });
menu.push({ text: intl.formatMessage(messages.bookmarks), to: '/bookmarks' });
menu.push({ text: intl.formatMessage(messages.lists), to: '/lists' });
menu.push({ text: intl.formatMessage(messages.followed_tags), to: '/followed_tags' });
menu.push({ text: intl.formatMessage(messages.follow_requests), to: "/follow_requests" });
menu.push({ text: intl.formatMessage(messages.favourites), to: "/favourites" });
menu.push({ text: intl.formatMessage(messages.bookmarks), to: "/bookmarks" });
menu.push({ text: intl.formatMessage(messages.lists), to: "/lists" });
menu.push({ text: intl.formatMessage(messages.followed_tags), to: "/followed_tags" });
menu.push(null);
menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' });
menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' });
menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' });
menu.push({ text: intl.formatMessage(messages.filters), href: '/filters' });
menu.push({ text: intl.formatMessage(messages.mutes), to: "/mutes" });
menu.push({ text: intl.formatMessage(messages.blocks), to: "/blocks" });
menu.push({ text: intl.formatMessage(messages.domain_blocks), to: "/domain_blocks" });
menu.push({ text: intl.formatMessage(messages.filters), href: "/filters" });
menu.push(null);
menu.push({ text: intl.formatMessage(messages.logout), action: this.handleLogout });
@@ -1,8 +1,8 @@
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 '../../../components/avatar';
import { DisplayName } from '../../../components/display_name';
import { Avatar } from "../../../components/avatar";
import { DisplayName } from "../../../components/display_name";
export default class AutosuggestAccount extends ImmutablePureComponent {
@@ -14,7 +14,7 @@ export default class AutosuggestAccount extends ImmutablePureComponent {
const { account } = this.props;
return (
<div className='autosuggest-account' title={account.get('acct')}>
<div className='autosuggest-account' title={account.get("acct")}>
<div className='autosuggest-account-icon'><Avatar account={account} size={18} /></div>
<DisplayName account={account} />
</div>
@@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import PropTypes from "prop-types";
import { PureComponent } from "react";
import { length } from 'stringz';
import { length } from "stringz";
export default class CharacterCounter extends PureComponent {
@@ -1,42 +1,42 @@
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 { length } from 'stringz';
import { length } from "stringz";
import { Icon } from 'mastodon/components/icon';
import { Icon } from "mastodon/components/icon";
import AutosuggestInput from '../../../components/autosuggest_input';
import AutosuggestTextarea from '../../../components/autosuggest_textarea';
import Button from '../../../components/button';
import { maxChars } from '../../../initial_state';
import EmojiPickerDropdown from '../containers/emoji_picker_dropdown_container';
import LanguageDropdown from '../containers/language_dropdown_container';
import PollButtonContainer from '../containers/poll_button_container';
import PollFormContainer from '../containers/poll_form_container';
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
import ReplyIndicatorContainer from '../containers/reply_indicator_container';
import SpoilerButtonContainer from '../containers/spoiler_button_container';
import UploadButtonContainer from '../containers/upload_button_container';
import UploadFormContainer from '../containers/upload_form_container';
import WarningContainer from '../containers/warning_container';
import { countableText } from '../util/counter';
import AutosuggestInput from "../../../components/autosuggest_input";
import AutosuggestTextarea from "../../../components/autosuggest_textarea";
import Button from "../../../components/button";
import { maxChars } from "../../../initial_state";
import EmojiPickerDropdown from "../containers/emoji_picker_dropdown_container";
import LanguageDropdown from "../containers/language_dropdown_container";
import PollButtonContainer from "../containers/poll_button_container";
import PollFormContainer from "../containers/poll_form_container";
import PrivacyDropdownContainer from "../containers/privacy_dropdown_container";
import ReplyIndicatorContainer from "../containers/reply_indicator_container";
import SpoilerButtonContainer from "../containers/spoiler_button_container";
import UploadButtonContainer from "../containers/upload_button_container";
import UploadFormContainer from "../containers/upload_form_container";
import WarningContainer from "../containers/warning_container";
import { countableText } from "../util/counter";
import CharacterCounter from './character_counter';
import CharacterCounter from "./character_counter";
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
const allowedAroundShortCode = "><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d";
const messages = defineMessages({
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: '(Optional) post title / content warning' },
publish: { id: 'compose_form.publish', defaultMessage: 'Promulgate' },
publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' },
saveChanges: { id: 'compose_form.save_changes', defaultMessage: 'Save changes' },
placeholder: { id: "compose_form.placeholder", defaultMessage: "What is on your mind?" },
spoiler_placeholder: { id: "compose_form.spoiler_placeholder", defaultMessage: "(Optional) post title / content warning" },
publish: { id: "compose_form.publish", defaultMessage: "Promulgate" },
publishLoud: { id: "compose_form.publish_loud", defaultMessage: "{publish}!" },
saveChanges: { id: "compose_form.save_changes", defaultMessage: "Save changes" },
});
class ComposeForm extends ImmutablePureComponent {
@@ -93,7 +93,7 @@ class ComposeForm extends ImmutablePureComponent {
};
getFulltextForCharacterCounting = () => {
return [this.props.spoiler? this.props.spoilerText: '', countableText(this.props.text)].join('');
return [this.props.spoiler? this.props.spoilerText: "", countableText(this.props.text)].join("");
};
canSubmit = () => {
@@ -131,11 +131,11 @@ class ComposeForm extends ImmutablePureComponent {
};
onSuggestionSelected = (tokenStart, token, value) => {
this.props.onSuggestionSelected(tokenStart, token, value, ['text']);
this.props.onSuggestionSelected(tokenStart, token, value, ["text"]);
};
onSpoilerSuggestionSelected = (tokenStart, token, value) => {
this.props.onSuggestionSelected(tokenStart, token, value, ['spoiler_text']);
this.props.onSuggestionSelected(tokenStart, token, value, ["spoiler_text"]);
};
handleChangeSpoilerText = (e) => {
@@ -156,7 +156,9 @@ class ComposeForm extends ImmutablePureComponent {
}
componentWillUnmount () {
if (this.timeout) clearTimeout(this.timeout);
if (this.timeout) {
clearTimeout(this.timeout);
}
}
componentDidUpdate (prevProps) {
@@ -175,7 +177,7 @@ class ComposeForm extends ImmutablePureComponent {
if (this.props.preselectDate !== prevProps.preselectDate && this.props.isInReply) {
selectionEnd = this.props.text.length;
selectionStart = this.props.text.search(/\s/) + 1;
} else if (typeof this.props.caretPosition === 'number') {
} else if (typeof this.props.caretPosition === "number") {
selectionStart = this.props.caretPosition;
selectionEnd = this.props.caretPosition;
} else {
@@ -228,14 +230,14 @@ class ComposeForm extends ImmutablePureComponent {
const { highlighted } = this.state;
const disabled = this.props.isSubmitting;
let publishText = '';
let publishText = "";
if (this.props.isEditing) {
publishText = intl.formatMessage(messages.saveChanges);
} else if (this.props.privacy === 'private' || this.props.privacy === 'direct') {
} else if (this.props.privacy === "private" || this.props.privacy === "direct") {
publishText = <span className='compose-form__publish-private'><Icon id='lock' /> {intl.formatMessage(messages.publish)}</span>;
} else {
publishText = this.props.privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
publishText = this.props.privacy !== "unlisted" ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
}
return (
@@ -244,7 +246,7 @@ class ComposeForm extends ImmutablePureComponent {
<ReplyIndicatorContainer />
<div className={`spoiler-input ${this.props.spoiler ? 'spoiler-input--visible' : ''}`} ref={this.setRef} aria-hidden={!this.props.spoiler}>
<div className={`spoiler-input ${this.props.spoiler ? "spoiler-input--visible" : ""}`} ref={this.setRef} aria-hidden={!this.props.spoiler}>
<AutosuggestInput
placeholder={intl.formatMessage(messages.spoiler_placeholder)}
value={this.props.spoilerText}
@@ -256,7 +258,7 @@ class ComposeForm extends ImmutablePureComponent {
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSpoilerSuggestionSelected}
searchTokens={[':']}
searchTokens={[":"]}
id='cw-spoiler-input'
className='spoiler-input__input'
lang={this.props.lang}
@@ -264,7 +266,7 @@ class ComposeForm extends ImmutablePureComponent {
/>
</div>
<div className={classNames('compose-form__highlightable', { active: highlighted })}>
<div className={classNames("compose-form__highlightable", { active: highlighted })}>
<AutosuggestTextarea
ref={this.setAutosuggestTextarea}
placeholder={intl.formatMessage(messages.placeholder)}
@@ -1,34 +1,34 @@
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 ImmutablePropTypes from "react-immutable-proptypes";
import { supportsPassiveEvents } from 'detect-passive-events';
import Overlay from 'react-overlays/Overlay';
import { supportsPassiveEvents } from "detect-passive-events";
import Overlay from "react-overlays/Overlay";
import { assetHost } from 'mastodon/utils/config';
import { assetHost } from "mastodon/utils/config";
import { buildCustomEmojis, categoriesFromEmojis } from '../../emoji/emoji';
import { EmojiPicker as EmojiPickerAsync } from '../../ui/util/async-components';
import { buildCustomEmojis, categoriesFromEmojis } from "../../emoji/emoji";
import { EmojiPicker as EmojiPickerAsync } from "../../ui/util/async-components";
const messages = defineMessages({
emoji: { id: 'emoji_button.label', defaultMessage: 'Insert emoji' },
emoji_search: { id: 'emoji_button.search', defaultMessage: 'Search...' },
custom: { id: 'emoji_button.custom', defaultMessage: 'Custom' },
recent: { id: 'emoji_button.recent', defaultMessage: 'Frequently used' },
search_results: { id: 'emoji_button.search_results', defaultMessage: 'Search results' },
people: { id: 'emoji_button.people', defaultMessage: 'People' },
nature: { id: 'emoji_button.nature', defaultMessage: 'Nature' },
food: { id: 'emoji_button.food', defaultMessage: 'Food & Drink' },
activity: { id: 'emoji_button.activity', defaultMessage: 'Activity' },
travel: { id: 'emoji_button.travel', defaultMessage: 'Travel & Places' },
objects: { id: 'emoji_button.objects', defaultMessage: 'Objects' },
symbols: { id: 'emoji_button.symbols', defaultMessage: 'Symbols' },
flags: { id: 'emoji_button.flags', defaultMessage: 'Flags' },
emoji: { id: "emoji_button.label", defaultMessage: "Insert emoji" },
emoji_search: { id: "emoji_button.search", defaultMessage: "Search..." },
custom: { id: "emoji_button.custom", defaultMessage: "Custom" },
recent: { id: "emoji_button.recent", defaultMessage: "Frequently used" },
search_results: { id: "emoji_button.search_results", defaultMessage: "Search results" },
people: { id: "emoji_button.people", defaultMessage: "People" },
nature: { id: "emoji_button.nature", defaultMessage: "Nature" },
food: { id: "emoji_button.food", defaultMessage: "Food & Drink" },
activity: { id: "emoji_button.activity", defaultMessage: "Activity" },
travel: { id: "emoji_button.travel", defaultMessage: "Travel & Places" },
objects: { id: "emoji_button.objects", defaultMessage: "Objects" },
symbols: { id: "emoji_button.symbols", defaultMessage: "Symbols" },
flags: { id: "emoji_button.flags", defaultMessage: "Flags" },
});
let EmojiPicker, Emoji; // load asynchronously
@@ -62,7 +62,7 @@ class ModifierPickerMenu extends PureComponent {
};
handleClick = e => {
this.props.onSelect(e.currentTarget.getAttribute('data-index') * 1);
this.props.onSelect(e.currentTarget.getAttribute("data-index") * 1);
};
UNSAFE_componentWillReceiveProps (nextProps) {
@@ -84,13 +84,13 @@ class ModifierPickerMenu extends PureComponent {
};
attachListeners () {
document.addEventListener('click', this.handleDocumentClick, { capture: true });
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
document.addEventListener("click", this.handleDocumentClick, { capture: true });
document.addEventListener("touchend", this.handleDocumentClick, listenerOptions);
}
removeListeners () {
document.removeEventListener('click', this.handleDocumentClick, { capture: true });
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
document.removeEventListener("click", this.handleDocumentClick, { capture: true });
document.removeEventListener("touchend", this.handleDocumentClick, listenerOptions);
}
setRef = c => {
@@ -101,7 +101,7 @@ class ModifierPickerMenu extends PureComponent {
const { active } = this.props;
return (
<div className='emoji-picker-dropdown__modifiers__menu' style={{ display: active ? 'block' : 'none' }} ref={this.setRef}>
<div className='emoji-picker-dropdown__modifiers__menu' style={{ display: active ? "block" : "none" }} ref={this.setRef}>
<button type='button' onClick={this.handleClick} data-index={1}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={1} backgroundImageFn={backgroundImageFn} /></button>
<button type='button' onClick={this.handleClick} data-index={2}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={2} backgroundImageFn={backgroundImageFn} /></button>
<button type='button' onClick={this.handleClick} data-index={3}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={3} backgroundImageFn={backgroundImageFn} /></button>
@@ -182,23 +182,25 @@ class EmojiPickerMenuImpl extends PureComponent {
};
componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, { capture: true });
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
document.addEventListener("click", this.handleDocumentClick, { capture: true });
document.addEventListener("touchend", this.handleDocumentClick, listenerOptions);
// Because of https://github.com/react-bootstrap/react-bootstrap/issues/2614 we need
// to wait for a frame before focusing
requestAnimationFrame(() => {
this.setState({ readyToFocus: true });
if (this.node) {
const element = this.node.querySelector('input[type="search"]');
if (element) element.focus();
const element = this.node.querySelector("input[type=\"search\"]");
if (element) {
element.focus();
}
}
});
}
componentWillUnmount () {
document.removeEventListener('click', this.handleDocumentClick, { capture: true });
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
document.removeEventListener("click", this.handleDocumentClick, { capture: true });
document.removeEventListener("touchend", this.handleDocumentClick, listenerOptions);
}
setRef = c => {
@@ -260,21 +262,21 @@ class EmojiPickerMenuImpl extends PureComponent {
const { modifierOpen } = this.state;
const categoriesSort = [
'recent',
'people',
'nature',
'foods',
'activity',
'places',
'objects',
'symbols',
'flags',
"recent",
"people",
"nature",
"foods",
"activity",
"places",
"objects",
"symbols",
"flags",
];
categoriesSort.splice(1, 0, ...Array.from(categoriesFromEmojis(custom_emojis)).sort());
return (
<div className={classNames('emoji-picker-dropdown__menu', { selecting: modifierOpen })} style={style} ref={this.setRef}>
<div className={classNames("emoji-picker-dropdown__menu", { selecting: modifierOpen })} style={style} ref={this.setRef}>
<EmojiPicker
perLine={8}
emojiSize={22}
@@ -355,7 +357,7 @@ class EmojiPickerDropdown extends PureComponent {
};
onToggle = (e) => {
if (!this.state.loading && (!e.key || e.key === 'Enter')) {
if (!this.state.loading && (!e.key || e.key === "Enter")) {
if (this.state.active) {
this.onHideDropdown();
} else {
@@ -365,7 +367,7 @@ class EmojiPickerDropdown extends PureComponent {
};
handleKeyDown = e => {
if (e.key === 'Escape') {
if (e.key === "Escape") {
this.onHideDropdown();
}
};
@@ -387,13 +389,13 @@ class EmojiPickerDropdown extends PureComponent {
<div className='emoji-picker-dropdown' onKeyDown={this.handleKeyDown}>
<div ref={this.setTargetRef} className='emoji-button' title={title} aria-label={title} aria-expanded={active} role='button' onClick={this.onToggle} onKeyDown={this.onToggle} tabIndex={0}>
{button || <img
className={classNames('emojione', { 'pulse-loading': active && loading })}
className={classNames("emojione", { "pulse-loading": active && loading })}
alt='🙂'
src={`${assetHost}/emoji/1f642.svg`}
/>}
</div>
<Overlay show={active} placement={'bottom'} target={this.findTarget} popperConfig={{ strategy: 'fixed' }}>
<Overlay show={active} placement={"bottom"} target={this.findTarget} popperConfig={{ strategy: "fixed" }}>
{({ props, placement })=> (
<div {...props} style={{ ...props.style, width: 299 }}>
<div className={`dropdown-animation ${placement}`}>
@@ -1,23 +1,23 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import PropTypes from "prop-types";
import { PureComponent } from "react";
import { injectIntl, defineMessages } from 'react-intl';
import { injectIntl, defineMessages } from "react-intl";
import classNames from 'classnames';
import classNames from "classnames";
import { supportsPassiveEvents } from 'detect-passive-events';
import fuzzysort from 'fuzzysort';
import Overlay from 'react-overlays/Overlay';
import { supportsPassiveEvents } from "detect-passive-events";
import fuzzysort from "fuzzysort";
import Overlay from "react-overlays/Overlay";
import { languages as preloadedLanguages } from 'mastodon/initial_state';
import { loupeIcon, deleteIcon } from 'mastodon/utils/icons';
import { languages as preloadedLanguages } from "mastodon/initial_state";
import { loupeIcon, deleteIcon } from "mastodon/utils/icons";
import TextIconButton from './text_icon_button';
import TextIconButton from "./text_icon_button";
const messages = defineMessages({
changeLanguage: { id: 'compose.language.change', defaultMessage: 'Change language' },
search: { id: 'compose.language.search', defaultMessage: 'Search languages...' },
clear: { id: 'emoji_button.clear', defaultMessage: 'Clear' },
changeLanguage: { id: "compose.language.change", defaultMessage: "Change language" },
search: { id: "compose.language.search", defaultMessage: "Search languages..." },
clear: { id: "emoji_button.clear", defaultMessage: "Clear" },
});
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
@@ -38,7 +38,7 @@ class LanguageDropdownMenu extends PureComponent {
};
state = {
searchValue: '',
searchValue: "",
};
handleDocumentClick = e => {
@@ -49,22 +49,24 @@ class LanguageDropdownMenu extends PureComponent {
};
componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, { capture: true });
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
document.addEventListener("click", this.handleDocumentClick, { capture: true });
document.addEventListener("touchend", this.handleDocumentClick, listenerOptions);
// Because of https://github.com/react-bootstrap/react-bootstrap/issues/2614 we need
// to wait for a frame before focusing
requestAnimationFrame(() => {
if (this.node) {
const element = this.node.querySelector('input[type="search"]');
if (element) element.focus();
const element = this.node.querySelector("input[type=\"search\"]");
if (element) {
element.focus();
}
}
});
}
componentWillUnmount () {
document.removeEventListener('click', this.handleDocumentClick, { capture: true });
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
document.removeEventListener("click", this.handleDocumentClick, { capture: true });
document.removeEventListener("touchend", this.handleDocumentClick, listenerOptions);
}
setRef = c => {
@@ -83,7 +85,7 @@ class LanguageDropdownMenu extends PureComponent {
const { languages, value, frequentlyUsedLanguages } = this.props;
const { searchValue } = this.state;
if (searchValue === '') {
if (searchValue === "") {
return [...languages].sort((a, b) => {
// Push current selection to the top of the list
@@ -103,7 +105,7 @@ class LanguageDropdownMenu extends PureComponent {
}
return fuzzysort.go(searchValue, languages, {
keys: ['0', '1', '2'],
keys: ["0", "1", "2"],
limit: 5,
threshold: -10000,
}).map(result => result.obj);
@@ -122,7 +124,7 @@ class LanguageDropdownMenu extends PureComponent {
}
handleClick = e => {
const value = e.currentTarget.getAttribute('data-index');
const value = e.currentTarget.getAttribute("data-index");
e.preventDefault();
@@ -137,31 +139,31 @@ class LanguageDropdownMenu extends PureComponent {
let element = null;
switch(e.key) {
case 'Escape':
onClose();
break;
case 'Enter':
this.handleClick(e);
break;
case 'ArrowDown':
element = this.listNode.childNodes[index + 1] || this.listNode.firstChild;
break;
case 'ArrowUp':
element = this.listNode.childNodes[index - 1] || this.listNode.lastChild;
break;
case 'Tab':
if (e.shiftKey) {
element = this.listNode.childNodes[index - 1] || this.listNode.lastChild;
} else {
case "Escape":
onClose();
break;
case "Enter":
this.handleClick(e);
break;
case "ArrowDown":
element = this.listNode.childNodes[index + 1] || this.listNode.firstChild;
}
break;
case 'Home':
element = this.listNode.firstChild;
break;
case 'End':
element = this.listNode.lastChild;
break;
break;
case "ArrowUp":
element = this.listNode.childNodes[index - 1] || this.listNode.lastChild;
break;
case "Tab":
if (e.shiftKey) {
element = this.listNode.childNodes[index - 1] || this.listNode.lastChild;
} else {
element = this.listNode.childNodes[index + 1] || this.listNode.firstChild;
}
break;
case "Home":
element = this.listNode.firstChild;
break;
case "End":
element = this.listNode.lastChild;
break;
}
if (element) {
@@ -178,44 +180,44 @@ class LanguageDropdownMenu extends PureComponent {
let element = null;
switch(e.key) {
case 'Tab':
case 'ArrowDown':
element = this.listNode.firstChild;
case "Tab":
case "ArrowDown":
element = this.listNode.firstChild;
if (element) {
element.focus();
e.preventDefault();
e.stopPropagation();
}
if (element) {
element.focus();
e.preventDefault();
e.stopPropagation();
}
break;
case 'Enter':
element = this.listNode.firstChild;
break;
case "Enter":
element = this.listNode.firstChild;
if (element) {
onChange(element.getAttribute('data-index'));
onClose();
}
break;
case 'Escape':
if (searchValue !== '') {
e.preventDefault();
this.handleClear();
}
if (element) {
onChange(element.getAttribute("data-index"));
onClose();
}
break;
case "Escape":
if (searchValue !== "") {
e.preventDefault();
this.handleClear();
}
break;
break;
}
};
handleClear = () => {
this.setState({ searchValue: '' });
this.setState({ searchValue: "" });
};
renderItem = lang => {
const { value } = this.props;
return (
<div key={lang[0]} role='option' tabIndex={0} data-index={lang[0]} className={classNames('language-dropdown__dropdown__results__item', { active: lang[0] === value })} aria-selected={lang[0] === value} onClick={this.handleClick} onKeyDown={this.handleKeyDown}>
<div key={lang[0]} role='option' tabIndex={0} data-index={lang[0]} className={classNames("language-dropdown__dropdown__results__item", { active: lang[0] === value })} aria-selected={lang[0] === value} onClick={this.handleClick} onKeyDown={this.handleKeyDown}>
<span className='language-dropdown__dropdown__results__item__native-name' lang={lang[0]}>{lang[2]}</span> <span className='language-dropdown__dropdown__results__item__common-name'>({lang[1]})</span>
</div>
);
@@ -224,7 +226,7 @@ class LanguageDropdownMenu extends PureComponent {
render () {
const { intl } = this.props;
const { searchValue } = this.state;
const isSearching = searchValue !== '';
const isSearching = searchValue !== "";
const results = this.search();
return (
@@ -255,7 +257,7 @@ class LanguageDropdown extends PureComponent {
state = {
open: false,
placement: 'bottom',
placement: "bottom",
};
handleToggle = () => {
@@ -299,7 +301,7 @@ class LanguageDropdown extends PureComponent {
const { open, placement } = this.state;
return (
<div className={classNames('privacy-dropdown', placement, { active: open })}>
<div className={classNames("privacy-dropdown", placement, { active: open })}>
<div className='privacy-dropdown__value' ref={this.setTargetRef} >
<TextIconButton
className='privacy-dropdown__value-icon'
@@ -310,7 +312,7 @@ class LanguageDropdown extends PureComponent {
/>
</div>
<Overlay show={open} placement={'bottom'} flip target={this.findTarget} popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}>
<Overlay show={open} placement={"bottom"} flip target={this.findTarget} popperConfig={{ strategy: "fixed", onFirstUpdate: this.handleOverlayEnter }}>
{({ props, placement }) => (
<div {...props}>
<div className={`dropdown-animation language-dropdown__dropdown ${placement}`} >
@@ -1,15 +1,15 @@
import PropTypes from 'prop-types';
import PropTypes from "prop-types";
import { FormattedMessage } from 'react-intl';
import { FormattedMessage } from "react-intl";
import { Link } from 'react-router-dom';
import { Link } from "react-router-dom";
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 '../../../components/avatar';
import { Avatar } from "../../../components/avatar";
import ActionBar from './action_bar';
import ActionBar from "./action_bar";
export default class NavigationBar extends ImmutablePureComponent {
@@ -20,11 +20,11 @@ export default class NavigationBar extends ImmutablePureComponent {
};
render () {
const username = this.props.account.get('acct');
const username = this.props.account.get("acct");
return (
<div className='navigation-bar'>
<Link to={`/@${username}`}>
<span style={{ display: 'none' }}>{username}</span>
<span style={{ display: "none" }}>{username}</span>
<Avatar account={this.props.account} size={46} />
</Link>
@@ -1,18 +1,18 @@
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 '../../../components/icon_button';
import { IconButton } from "../../../components/icon_button";
const messages = defineMessages({
add_poll: { id: 'poll_button.add_poll', defaultMessage: 'Add a poll' },
remove_poll: { id: 'poll_button.remove_poll', defaultMessage: 'Remove poll' },
add_poll: { id: "poll_button.add_poll", defaultMessage: "Add a poll" },
remove_poll: { id: "poll_button.remove_poll", defaultMessage: "Remove poll" },
});
const iconStyle = {
height: null,
lineHeight: '27px',
lineHeight: "27px",
};
class PollButton extends PureComponent {
@@ -43,7 +43,7 @@ class PollButton extends PureComponent {
title={intl.formatMessage(active ? messages.remove_poll : messages.add_poll)}
disabled={disabled}
onClick={this.handleClick}
className={`compose-form__poll-button-icon ${active ? 'active' : ''}`}
className={`compose-form__poll-button-icon ${active ? "active" : ""}`}
size={18}
inverted
style={iconStyle}
@@ -1,27 +1,27 @@
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 ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from "react-immutable-proptypes";
import ImmutablePureComponent from "react-immutable-pure-component";
import AutosuggestInput from 'mastodon/components/autosuggest_input';
import { Icon } from 'mastodon/components/icon';
import { IconButton } from 'mastodon/components/icon_button';
import AutosuggestInput from "mastodon/components/autosuggest_input";
import { Icon } from "mastodon/components/icon";
import { IconButton } from "mastodon/components/icon_button";
const messages = defineMessages({
option_placeholder: { id: 'compose_form.poll.option_placeholder', defaultMessage: 'Choice {number}' },
add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add a choice' },
remove_option: { id: 'compose_form.poll.remove_option', defaultMessage: 'Remove this choice' },
poll_duration: { id: 'compose_form.poll.duration', defaultMessage: 'Poll duration' },
switchToMultiple: { id: 'compose_form.poll.switch_to_multiple', defaultMessage: 'Change poll to allow multiple choices' },
switchToSingle: { id: 'compose_form.poll.switch_to_single', defaultMessage: 'Change poll to allow for a single choice' },
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}}' },
option_placeholder: { id: "compose_form.poll.option_placeholder", defaultMessage: "Choice {number}" },
add_option: { id: "compose_form.poll.add_option", defaultMessage: "Add a choice" },
remove_option: { id: "compose_form.poll.remove_option", defaultMessage: "Remove this choice" },
poll_duration: { id: "compose_form.poll.duration", defaultMessage: "Poll duration" },
switchToMultiple: { id: "compose_form.poll.switch_to_multiple", defaultMessage: "Change poll to allow multiple choices" },
switchToSingle: { id: "compose_form.poll.switch_to_single", defaultMessage: "Change poll to allow for a single choice" },
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}}" },
});
class OptionIntl extends PureComponent {
@@ -58,7 +58,7 @@ class OptionIntl extends PureComponent {
};
handleCheckboxKeypress = e => {
if (e.key === 'Enter' || e.key === ' ') {
if (e.key === "Enter" || e.key === " ") {
this.handleToggleMultiple(e);
}
};
@@ -72,7 +72,7 @@ class OptionIntl extends PureComponent {
};
onSuggestionSelected = (tokenStart, token, value) => {
this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]);
this.props.onSuggestionSelected(tokenStart, token, value, ["poll", "options", this.props.index]);
};
render () {
@@ -82,7 +82,7 @@ class OptionIntl extends PureComponent {
<li>
<label className='poll__option editable'>
<span
className={classNames('poll__input', { checkbox: isPollMultiple })}
className={classNames("poll__input", { checkbox: isPollMultiple })}
onClick={this.handleToggleMultiple}
onKeyPress={this.handleCheckboxKeypress}
role='button'
@@ -102,7 +102,7 @@ class OptionIntl extends PureComponent {
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSuggestionSelected}
searchTokens={[':']}
searchTokens={[":"]}
autoFocus={autoFocus}
/>
</label>
@@ -137,7 +137,7 @@ class PollForm extends ImmutablePureComponent {
};
handleAddOption = () => {
this.props.onAddOption('');
this.props.onAddOption("");
};
handleSelectDuration = e => {
@@ -155,7 +155,7 @@ class PollForm extends ImmutablePureComponent {
return null;
}
const autoFocusIndex = options.indexOf('');
const autoFocusIndex = options.indexOf("");
return (
<div className='compose-form__poll-wrapper'>
@@ -1,27 +1,27 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import PropTypes from "prop-types";
import { PureComponent } from "react";
import { injectIntl, defineMessages } from 'react-intl';
import { injectIntl, defineMessages } from "react-intl";
import classNames from 'classnames';
import classNames from "classnames";
import { supportsPassiveEvents } from 'detect-passive-events';
import Overlay from 'react-overlays/Overlay';
import { supportsPassiveEvents } from "detect-passive-events";
import Overlay from "react-overlays/Overlay";
import { Icon } from 'mastodon/components/icon';
import { Icon } from "mastodon/components/icon";
import { IconButton } from '../../../components/icon_button';
import { IconButton } from "../../../components/icon_button";
const messages = defineMessages({
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
public_long: { id: 'privacy.public.long', defaultMessage: 'Visible for all' },
unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
unlisted_long: { id: 'privacy.unlisted.long', defaultMessage: 'Visible for all, but opted-out of discovery features' },
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers only' },
private_long: { id: 'privacy.private.long', defaultMessage: 'Visible for followers only' },
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
direct_long: { id: 'privacy.direct.long', defaultMessage: 'Visible for mentioned users only' },
change_privacy: { id: 'privacy.change', defaultMessage: 'Adjust status privacy' },
public_short: { id: "privacy.public.short", defaultMessage: "Public" },
public_long: { id: "privacy.public.long", defaultMessage: "Visible for all" },
unlisted_short: { id: "privacy.unlisted.short", defaultMessage: "Unlisted" },
unlisted_long: { id: "privacy.unlisted.long", defaultMessage: "Visible for all, but opted-out of discovery features" },
private_short: { id: "privacy.private.short", defaultMessage: "Followers only" },
private_long: { id: "privacy.private.long", defaultMessage: "Visible for followers only" },
direct_short: { id: "privacy.direct.short", defaultMessage: "Mentioned people only" },
direct_long: { id: "privacy.direct.long", defaultMessage: "Visible for mentioned users only" },
change_privacy: { id: "privacy.change", defaultMessage: "Adjust status privacy" },
});
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
@@ -45,50 +45,50 @@ class PrivacyDropdownMenu extends PureComponent {
handleKeyDown = e => {
const { items } = this.props;
const value = e.currentTarget.getAttribute('data-index');
const value = e.currentTarget.getAttribute("data-index");
const index = items.findIndex(item => {
return (item.value === value);
});
let element = null;
switch(e.key) {
case 'Escape':
this.props.onClose();
break;
case 'Enter':
this.handleClick(e);
break;
case 'ArrowDown':
element = this.node.childNodes[index + 1] || this.node.firstChild;
break;
case 'ArrowUp':
element = this.node.childNodes[index - 1] || this.node.lastChild;
break;
case 'Tab':
if (e.shiftKey) {
element = this.node.childNodes[index - 1] || this.node.lastChild;
} else {
case "Escape":
this.props.onClose();
break;
case "Enter":
this.handleClick(e);
break;
case "ArrowDown":
element = this.node.childNodes[index + 1] || this.node.firstChild;
}
break;
case 'Home':
element = this.node.firstChild;
break;
case 'End':
element = this.node.lastChild;
break;
break;
case "ArrowUp":
element = this.node.childNodes[index - 1] || this.node.lastChild;
break;
case "Tab":
if (e.shiftKey) {
element = this.node.childNodes[index - 1] || this.node.lastChild;
} else {
element = this.node.childNodes[index + 1] || this.node.firstChild;
}
break;
case "Home":
element = this.node.firstChild;
break;
case "End":
element = this.node.lastChild;
break;
}
if (element) {
element.focus();
this.props.onChange(element.getAttribute('data-index'));
this.props.onChange(element.getAttribute("data-index"));
e.preventDefault();
e.stopPropagation();
}
};
handleClick = e => {
const value = e.currentTarget.getAttribute('data-index');
const value = e.currentTarget.getAttribute("data-index");
e.preventDefault();
@@ -97,14 +97,16 @@ class PrivacyDropdownMenu extends PureComponent {
};
componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, { capture: true });
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
if (this.focusedItem) this.focusedItem.focus({ preventScroll: true });
document.addEventListener("click", this.handleDocumentClick, { capture: true });
document.addEventListener("touchend", this.handleDocumentClick, listenerOptions);
if (this.focusedItem) {
this.focusedItem.focus({ preventScroll: true });
}
}
componentWillUnmount () {
document.removeEventListener('click', this.handleDocumentClick, { capture: true });
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
document.removeEventListener("click", this.handleDocumentClick, { capture: true });
document.removeEventListener("touchend", this.handleDocumentClick, listenerOptions);
}
setRef = c => {
@@ -121,7 +123,7 @@ class PrivacyDropdownMenu extends PureComponent {
return (
<div style={{ ...style }} role='listbox' ref={this.setRef}>
{items.map(item => (
<div role='option' tabIndex={0} key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}>
<div role='option' tabIndex={0} key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames("privacy-dropdown__option", { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}>
<div className='privacy-dropdown__option__icon'>
<Icon id={item.icon} fixedWidth />
</div>
@@ -154,7 +156,7 @@ class PrivacyDropdown extends PureComponent {
state = {
open: false,
placement: 'bottom',
placement: "bottom",
};
handleToggle = () => {
@@ -178,7 +180,7 @@ class PrivacyDropdown extends PureComponent {
handleModalActionClick = (e) => {
e.preventDefault();
const { value } = this.options[e.currentTarget.getAttribute('data-index')];
const { value } = this.options[e.currentTarget.getAttribute("data-index")];
this.props.onModalClose();
this.props.onChange(value);
@@ -186,9 +188,9 @@ class PrivacyDropdown extends PureComponent {
handleKeyDown = e => {
switch(e.key) {
case 'Escape':
this.handleClose();
break;
case "Escape":
this.handleClose();
break;
}
};
@@ -200,10 +202,10 @@ class PrivacyDropdown extends PureComponent {
handleButtonKeyDown = (e) => {
switch(e.key) {
case ' ':
case 'Enter':
this.handleMouseDown();
break;
case " ":
case "Enter":
this.handleMouseDown();
break;
}
};
@@ -222,14 +224,14 @@ class PrivacyDropdown extends PureComponent {
const { intl: { formatMessage } } = this.props;
this.options = [
{ icon: 'globe', value: 'public', text: formatMessage(messages.public_short), meta: formatMessage(messages.public_long) },
{ icon: 'unlock', value: 'unlisted', text: formatMessage(messages.unlisted_short), meta: formatMessage(messages.unlisted_long) },
{ icon: 'lock', value: 'private', text: formatMessage(messages.private_short), meta: formatMessage(messages.private_long) },
{ icon: "globe", value: "public", text: formatMessage(messages.public_short), meta: formatMessage(messages.public_long) },
{ icon: "unlock", value: "unlisted", text: formatMessage(messages.unlisted_short), meta: formatMessage(messages.unlisted_long) },
{ icon: "lock", value: "private", text: formatMessage(messages.private_short), meta: formatMessage(messages.private_long) },
];
if (!this.props.noDirect) {
this.options.push(
{ icon: 'at', value: 'direct', text: formatMessage(messages.direct_short), meta: formatMessage(messages.direct_long) },
{ icon: "at", value: "direct", text: formatMessage(messages.direct_short), meta: formatMessage(messages.direct_long) },
);
}
}
@@ -253,8 +255,8 @@ class PrivacyDropdown extends PureComponent {
const valueOption = this.options.find(item => item.value === value);
return (
<div className={classNames('privacy-dropdown', placement, { active: open })} onKeyDown={this.handleKeyDown}>
<div className={classNames('privacy-dropdown__value', { active: this.options.indexOf(valueOption) === (placement === 'bottom' ? 0 : (this.options.length - 1)) })} ref={this.setTargetRef}>
<div className={classNames("privacy-dropdown", placement, { active: open })} onKeyDown={this.handleKeyDown}>
<div className={classNames("privacy-dropdown__value", { active: this.options.indexOf(valueOption) === (placement === "bottom" ? 0 : (this.options.length - 1)) })} ref={this.setTargetRef}>
<IconButton
className='privacy-dropdown__value-icon'
icon={valueOption.icon}
@@ -266,12 +268,12 @@ class PrivacyDropdown extends PureComponent {
onClick={this.handleToggle}
onMouseDown={this.handleMouseDown}
onKeyDown={this.handleButtonKeyDown}
style={{ height: null, lineHeight: '27px' }}
style={{ height: null, lineHeight: "27px" }}
disabled={disabled}
/>
</div>
<Overlay show={open} placement={'bottom'} flip target={this.findTarget} container={container} popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}>
<Overlay show={open} placement={"bottom"} flip target={this.findTarget} container={container} popperConfig={{ strategy: "fixed", onFirstUpdate: this.handleOverlayEnter }}>
{({ props, placement }) => (
<div {...props}>
<div className={`dropdown-animation privacy-dropdown__dropdown ${placement}`}>
@@ -1,18 +1,18 @@
import PropTypes from 'prop-types';
import PropTypes from "prop-types";
import { defineMessages, injectIntl } from 'react-intl';
import { defineMessages, injectIntl } from "react-intl";
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 'mastodon/components/attachment_list';
import AttachmentList from "mastodon/components/attachment_list";
import { Avatar } from '../../../components/avatar';
import { DisplayName } from '../../../components/display_name';
import { IconButton } from '../../../components/icon_button';
import { Avatar } from "../../../components/avatar";
import { DisplayName } from "../../../components/display_name";
import { IconButton } from "../../../components/icon_button";
const messages = defineMessages({
cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' },
cancel: { id: "reply_indicator.cancel", defaultMessage: "Cancel" },
});
class ReplyIndicator extends ImmutablePureComponent {
@@ -34,7 +34,7 @@ class ReplyIndicator extends ImmutablePureComponent {
handleAccountClick = (e) => {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
this.context.router.history.push(`/@${this.props.status.getIn(["account", "acct"])}`);
}
};
@@ -45,25 +45,25 @@ class ReplyIndicator extends ImmutablePureComponent {
return null;
}
const content = { __html: status.get('contentHtml') };
const content = { __html: status.get("contentHtml") };
return (
<div className='reply-indicator'>
<div className='reply-indicator__header'>
<div className='reply-indicator__cancel'><IconButton title={intl.formatMessage(messages.cancel)} icon='times' onClick={this.handleClick} inverted /></div>
<a href={`/@${status.getIn(['account', 'acct'])}`} onClick={this.handleAccountClick} className='reply-indicator__display-name'>
<div className='reply-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div>
<DisplayName account={status.get('account')} />
<a href={`/@${status.getIn(["account", "acct"])}`} onClick={this.handleAccountClick} className='reply-indicator__display-name'>
<div className='reply-indicator__display-avatar'><Avatar account={status.get("account")} size={24} /></div>
<DisplayName account={status.get("account")} />
</a>
</div>
<div className='reply-indicator__content translate' dangerouslySetInnerHTML={content} />
{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,29 +1,29 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import PropTypes from "prop-types";
import { PureComponent } from "react";
import { defineMessages, injectIntl, FormattedMessage, FormattedList } from 'react-intl';
import { defineMessages, injectIntl, FormattedMessage, FormattedList } from "react-intl";
import classNames from 'classnames';
import classNames from "classnames";
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePropTypes from "react-immutable-proptypes";
import { Icon } from 'mastodon/components/icon';
import { domain, searchEnabled } from 'mastodon/initial_state';
import { HASHTAG_REGEX } from 'mastodon/utils/hashtags';
import { Icon } from "mastodon/components/icon";
import { domain, searchEnabled } from "mastodon/initial_state";
import { HASHTAG_REGEX } from "mastodon/utils/hashtags";
const messages = defineMessages({
placeholder: { id: 'search.placeholder', defaultMessage: 'Search' },
placeholderSignedIn: { id: 'search.search_or_paste', defaultMessage: 'Search or paste URL' },
placeholder: { id: "search.placeholder", defaultMessage: "Search" },
placeholderSignedIn: { id: "search.search_or_paste", defaultMessage: "Search or paste URL" },
});
const labelForRecentSearch = search => {
switch(search.get('type')) {
case 'account':
return `@${search.get('q')}`;
case 'hashtag':
return `#${search.get('q')}`;
default:
return search.get('q');
switch(search.get("type")) {
case "account":
return `@${search.get("q")}`;
case "hashtag":
return `#${search.get("q")}`;
default:
return search.get("q");
}
};
@@ -57,14 +57,30 @@ class Search extends PureComponent {
};
defaultOptions = [
{ label: <><mark>has:</mark> <FormattedList type='disjunction' value={['media', 'poll', 'embed']} /></>, action: e => { e.preventDefault(); this._insertText('has:'); } },
{ label: <><mark>is:</mark> <FormattedList type='disjunction' value={['reply', 'sensitive']} /></>, action: e => { e.preventDefault(); this._insertText('is:'); } },
{ label: <><mark>language:</mark> <FormattedMessage id='search_popout.language_code' defaultMessage='ISO language code' /></>, action: e => { e.preventDefault(); this._insertText('language:'); } },
{ label: <><mark>from:</mark> <FormattedMessage id='search_popout.user' defaultMessage='user' /></>, action: e => { e.preventDefault(); this._insertText('from:'); } },
{ label: <><mark>before:</mark> <FormattedMessage id='search_popout.specific_date' defaultMessage='specific date' /></>, action: e => { e.preventDefault(); this._insertText('before:'); } },
{ label: <><mark>during:</mark> <FormattedMessage id='search_popout.specific_date' defaultMessage='specific date' /></>, action: e => { e.preventDefault(); this._insertText('during:'); } },
{ label: <><mark>after:</mark> <FormattedMessage id='search_popout.specific_date' defaultMessage='specific date' /></>, action: e => { e.preventDefault(); this._insertText('after:'); } },
{ label: <><mark>in:</mark> <FormattedList type='disjunction' value={['all', 'library']} /></>, action: e => { e.preventDefault(); this._insertText('in:'); } }
{ label: <><mark>has:</mark> <FormattedList type='disjunction' value={["media", "poll", "embed"]} /></>, action: e => {
e.preventDefault(); this._insertText("has:");
} },
{ label: <><mark>is:</mark> <FormattedList type='disjunction' value={["reply", "sensitive"]} /></>, action: e => {
e.preventDefault(); this._insertText("is:");
} },
{ label: <><mark>language:</mark> <FormattedMessage id='search_popout.language_code' defaultMessage='ISO language code' /></>, action: e => {
e.preventDefault(); this._insertText("language:");
} },
{ label: <><mark>from:</mark> <FormattedMessage id='search_popout.user' defaultMessage='user' /></>, action: e => {
e.preventDefault(); this._insertText("from:");
} },
{ label: <><mark>before:</mark> <FormattedMessage id='search_popout.specific_date' defaultMessage='specific date' /></>, action: e => {
e.preventDefault(); this._insertText("before:");
} },
{ label: <><mark>during:</mark> <FormattedMessage id='search_popout.specific_date' defaultMessage='specific date' /></>, action: e => {
e.preventDefault(); this._insertText("during:");
} },
{ label: <><mark>after:</mark> <FormattedMessage id='search_popout.specific_date' defaultMessage='specific date' /></>, action: e => {
e.preventDefault(); this._insertText("after:");
} },
{ label: <><mark>in:</mark> <FormattedList type='disjunction' value={["all", "library"]} /></>, action: e => {
e.preventDefault(); this._insertText("in:");
} },
];
setRef = c => {
@@ -95,48 +111,48 @@ class Search extends PureComponent {
const options = searchEnabled ? this._getOptions().concat(this.defaultOptions) : this._getOptions();
switch(e.key) {
case 'Escape':
e.preventDefault();
this._unfocus();
case "Escape":
e.preventDefault();
this._unfocus();
break;
case 'ArrowDown':
e.preventDefault();
break;
case "ArrowDown":
e.preventDefault();
if (options.length > 0) {
this.setState({ selectedOption: Math.min(selectedOption + 1, options.length - 1) });
}
break;
case 'ArrowUp':
e.preventDefault();
if (options.length > 0) {
this.setState({ selectedOption: Math.max(selectedOption - 1, -1) });
}
break;
case 'Enter':
e.preventDefault();
if (selectedOption === -1) {
this._submit();
} else if (options.length > 0) {
options[selectedOption].action(e);
}
break;
case 'Delete':
if (selectedOption > -1 && options.length > 0) {
const search = options[selectedOption];
if (typeof search.forget === 'function') {
e.preventDefault();
search.forget(e);
if (options.length > 0) {
this.setState({ selectedOption: Math.min(selectedOption + 1, options.length - 1) });
}
}
break;
break;
case "ArrowUp":
e.preventDefault();
if (options.length > 0) {
this.setState({ selectedOption: Math.max(selectedOption - 1, -1) });
}
break;
case "Enter":
e.preventDefault();
if (selectedOption === -1) {
this._submit();
} else if (options.length > 0) {
options[selectedOption].action(e);
}
break;
case "Delete":
if (selectedOption > -1 && options.length > 0) {
const search = options[selectedOption];
if (typeof search.forget === "function") {
e.preventDefault();
search.forget(e);
}
}
break;
}
};
@@ -163,10 +179,10 @@ class Search extends PureComponent {
const { router } = this.context;
const { value, onClickSearchResult } = this.props;
const query = value.trim().replace(/^#/, '');
const query = value.trim().replace(/^#/, "");
router.history.push(`/tags/${query}`);
onClickSearchResult(query, 'hashtag');
onClickSearchResult(query, "hashtag");
this._unfocus();
};
@@ -174,10 +190,10 @@ class Search extends PureComponent {
const { router } = this.context;
const { value, onClickSearchResult } = this.props;
const query = value.trim().replace(/^@/, '');
const query = value.trim().replace(/^@/, "");
router.history.push(`/@${query}`);
onClickSearchResult(query, 'account');
onClickSearchResult(query, "account");
this._unfocus();
};
@@ -190,24 +206,24 @@ class Search extends PureComponent {
};
handleStatusSearch = () => {
this._submit('statuses');
this._submit("statuses");
};
handleAccountSearch = () => {
this._submit('accounts');
this._submit("accounts");
};
handleRecentSearchClick = search => {
const { onChange } = this.props;
const { router } = this.context;
if (search.get('type') === 'account') {
router.history.push(`/@${search.get('q')}`);
} else if (search.get('type') === 'hashtag') {
router.history.push(`/tags/${search.get('q')}`);
if (search.get("type") === "account") {
router.history.push(`/@${search.get("q")}`);
} else if (search.get("type") === "hashtag") {
router.history.push(`/tags/${search.get("q")}`);
} else {
onChange(search.get('q'));
this._submit(search.get('type'));
onChange(search.get("q"));
this._submit(search.get("type"));
}
this._unfocus();
@@ -216,19 +232,19 @@ class Search extends PureComponent {
handleForgetRecentSearchClick = search => {
const { onForgetSearchResult } = this.props;
onForgetSearchResult(search.get('q'));
onForgetSearchResult(search.get("q"));
};
_unfocus () {
document.querySelector('.ui').parentElement.focus();
document.querySelector(".ui").parentElement.focus();
}
_insertText (text) {
const { value, onChange } = this.props;
if (value === '') {
if (value === "") {
onChange(text);
} else if (value[value.length - 1] === ' ') {
} else if (value[value.length - 1] === " ") {
onChange(`${value}${text}`);
} else {
onChange(`${value} ${text}`);
@@ -246,7 +262,7 @@ class Search extends PureComponent {
}
if (openInRoute) {
router.history.push('/search');
router.history.push("/search");
}
this._unfocus();
@@ -278,34 +294,34 @@ class Search extends PureComponent {
const options = [];
if (trimmedValue.length > 0) {
const couldBeURL = trimmedValue.startsWith('https://') && !trimmedValue.includes(' ');
const couldBeURL = trimmedValue.startsWith("https://") && !trimmedValue.includes(" ");
if (couldBeURL) {
options.push({ key: 'open-url', label: <FormattedMessage id='search.quick_action.open_url' defaultMessage='Open URL in Mastodon' />, action: this.handleURLClick });
options.push({ key: "open-url", label: <FormattedMessage id='search.quick_action.open_url' defaultMessage='Open URL in Mastodon' />, action: this.handleURLClick });
}
const couldBeHashtag = (trimmedValue.startsWith('#') && trimmedValue.length > 1) || trimmedValue.match(HASHTAG_REGEX);
const couldBeHashtag = (trimmedValue.startsWith("#") && trimmedValue.length > 1) || trimmedValue.match(HASHTAG_REGEX);
if (couldBeHashtag) {
options.push({ key: 'go-to-hashtag', label: <FormattedMessage id='search.quick_action.go_to_hashtag' defaultMessage='Go to hashtag {x}' values={{ x: <mark>#{trimmedValue.replace(/^#/, '')}</mark> }} />, action: this.handleHashtagClick });
options.push({ key: "go-to-hashtag", label: <FormattedMessage id='search.quick_action.go_to_hashtag' defaultMessage='Go to hashtag {x}' values={{ x: <mark>#{trimmedValue.replace(/^#/, "")}</mark> }} />, action: this.handleHashtagClick });
}
const couldBeUsername = trimmedValue.match(/^@?[a-z0-9_-]+(@[^\s]+)?$/i);
if (couldBeUsername) {
options.push({ key: 'go-to-account', label: <FormattedMessage id='search.quick_action.go_to_account' defaultMessage='Go to profile {x}' values={{ x: <mark>@{trimmedValue.replace(/^@/, '')}</mark> }} />, action: this.handleAccountClick });
options.push({ key: "go-to-account", label: <FormattedMessage id='search.quick_action.go_to_account' defaultMessage='Go to profile {x}' values={{ x: <mark>@{trimmedValue.replace(/^@/, "")}</mark> }} />, action: this.handleAccountClick });
}
const couldBeStatusSearch = searchEnabled;
if (couldBeStatusSearch) {
options.push({ key: 'status-search', label: <FormattedMessage id='search.quick_action.status_search' defaultMessage='Posts matching {x}' values={{ x: <mark>{trimmedValue}</mark> }} />, action: this.handleStatusSearch });
options.push({ key: "status-search", label: <FormattedMessage id='search.quick_action.status_search' defaultMessage='Posts matching {x}' values={{ x: <mark>{trimmedValue}</mark> }} />, action: this.handleStatusSearch });
}
const couldBeUserSearch = true;
if (couldBeUserSearch) {
options.push({ key: 'account-search', label: <FormattedMessage id='search.quick_action.account_search' defaultMessage='Profiles matching {x}' values={{ x: <mark>{trimmedValue}</mark> }} />, action: this.handleAccountSearch });
options.push({ key: "account-search", label: <FormattedMessage id='search.quick_action.account_search' defaultMessage='Profiles matching {x}' values={{ x: <mark>{trimmedValue}</mark> }} />, action: this.handleAccountSearch });
}
}
@@ -320,7 +336,7 @@ class Search extends PureComponent {
const hasValue = value.length > 0 || submitted;
return (
<div className={classNames('search', { active: expanded })}>
<div className={classNames("search", { active: expanded })}>
<input
ref={this.setRef}
className='search__input'
@@ -335,8 +351,8 @@ class Search extends PureComponent {
/>
<div role='button' tabIndex={0} className='search__icon' onClick={this.handleClear}>
<Icon id='search' className={hasValue ? '' : 'active'} />
<Icon id='times-circle' className={hasValue ? 'active' : ''} aria-label={intl.formatMessage(messages.placeholder)} />
<Icon id='search' className={hasValue ? "" : "active"} />
<Icon id='times-circle' className={hasValue ? "active" : ""} aria-label={intl.formatMessage(messages.placeholder)} />
</div>
<div className='search__popout'>
@@ -346,7 +362,7 @@ class Search extends PureComponent {
<div className='search__popout__menu'>
{recent.size > 0 ? this._getOptions().map(({ label, action, forget }, i) => (
<button key={label} onMouseDown={action} className={classNames('search__popout__menu__item search__popout__menu__item--flex', { selected: selectedOption === i })}>
<button key={label} onMouseDown={action} className={classNames("search__popout__menu__item search__popout__menu__item--flex", { selected: selectedOption === i })}>
<span>{label}</span>
<button className='icon-button' onMouseDown={forget}><Icon id='times' /></button>
</button>
@@ -365,7 +381,7 @@ class Search extends PureComponent {
<div className='search__popout__menu'>
{options.map(({ key, label, action }, i) => (
<button key={key} onMouseDown={action} className={classNames('search__popout__menu__item', { selected: selectedOption === i })}>
<button key={key} onMouseDown={action} className={classNames("search__popout__menu__item", { selected: selectedOption === i })}>
{label}
</button>
))}
@@ -378,7 +394,7 @@ class Search extends PureComponent {
{searchEnabled ? (
<div className='search__popout__menu'>
{this.defaultOptions.map(({ key, label, action }, i) => (
<button key={key} onMouseDown={action} className={classNames('search__popout__menu__item', { selected: selectedOption === ((options.length || recent.size) + i) })}>
<button key={key} onMouseDown={action} className={classNames("search__popout__menu__item", { selected: selectedOption === ((options.length || recent.size) + i) })}>
{label}
</button>
))}
@@ -1,17 +1,17 @@
import PropTypes from 'prop-types';
import PropTypes from "prop-types";
import { FormattedMessage } from 'react-intl';
import { FormattedMessage } from "react-intl";
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 { Icon } from 'mastodon/components/icon';
import { LoadMore } from 'mastodon/components/load_more';
import { SearchSection } from 'mastodon/features/explore/components/search_section';
import { Icon } from "mastodon/components/icon";
import { LoadMore } from "mastodon/components/load_more";
import { SearchSection } from "mastodon/features/explore/components/search_section";
import { ImmutableHashtag as Hashtag } from '../../../components/hashtag';
import AccountContainer from '../../../containers/account_container';
import StatusContainer from '../../../containers/status_container';
import { ImmutableHashtag as Hashtag } from "../../../components/hashtag";
import AccountContainer from "../../../containers/account_container";
import StatusContainer from "../../../containers/status_container";
const INITIAL_PAGE_LIMIT = 10;
@@ -31,40 +31,40 @@ class SearchResults extends ImmutablePureComponent {
searchTerm: PropTypes.string,
};
handleLoadMoreAccounts = () => this.props.expandSearch('accounts');
handleLoadMoreAccounts = () => this.props.expandSearch("accounts");
handleLoadMoreStatuses = () => this.props.expandSearch('statuses');
handleLoadMoreStatuses = () => this.props.expandSearch("statuses");
handleLoadMoreHashtags = () => this.props.expandSearch('hashtags');
handleLoadMoreHashtags = () => this.props.expandSearch("hashtags");
render () {
const { results } = this.props;
let accounts, statuses, hashtags;
if (results.get('accounts') && results.get('accounts').size > 0) {
if (results.get("accounts") && results.get("accounts").size > 0) {
accounts = (
<SearchSection title={<><Icon id='users' fixedWidth /><FormattedMessage id='search_results.accounts' defaultMessage='Profiles' /></>}>
{withoutLastResult(results.get('accounts')).map(accountId => <AccountContainer key={accountId} id={accountId} />)}
{(results.get('accounts').size > INITIAL_PAGE_LIMIT && results.get('accounts').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreAccounts} />}
{withoutLastResult(results.get("accounts")).map(accountId => <AccountContainer key={accountId} id={accountId} />)}
{(results.get("accounts").size > INITIAL_PAGE_LIMIT && results.get("accounts").size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreAccounts} />}
</SearchSection>
);
}
if (results.get('hashtags') && results.get('hashtags').size > 0) {
if (results.get("hashtags") && results.get("hashtags").size > 0) {
hashtags = (
<SearchSection title={<><Icon id='hashtag' fixedWidth /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></>}>
{withoutLastResult(results.get('hashtags')).map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
{(results.get('hashtags').size > INITIAL_PAGE_LIMIT && results.get('hashtags').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreHashtags} />}
{withoutLastResult(results.get("hashtags")).map(hashtag => <Hashtag key={hashtag.get("name")} hashtag={hashtag} />)}
{(results.get("hashtags").size > INITIAL_PAGE_LIMIT && results.get("hashtags").size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreHashtags} />}
</SearchSection>
);
}
if (results.get('statuses') && results.get('statuses').size > 0) {
if (results.get("statuses") && results.get("statuses").size > 0) {
statuses = (
<SearchSection title={<><Icon id='quote-right' fixedWidth /><FormattedMessage id='search_results.statuses' defaultMessage='Posts' /></>}>
{withoutLastResult(results.get('statuses')).map(statusId => <StatusContainer key={statusId} id={statusId} />)}
{(results.get('statuses').size > INITIAL_PAGE_LIMIT && results.get('statuses').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreStatuses} />}
{withoutLastResult(results.get("statuses")).map(statusId => <StatusContainer key={statusId} id={statusId} />)}
{(results.get("statuses").size > INITIAL_PAGE_LIMIT && results.get("statuses").size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreStatuses} />}
</SearchSection>
);
}
@@ -1,9 +1,9 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import PropTypes from "prop-types";
import { PureComponent } from "react";
const iconStyle = {
height: null,
lineHeight: '27px',
lineHeight: "27px",
minWidth: `${18 * 1.28571429}px`,
};
@@ -25,7 +25,7 @@ export default class TextIconButton extends PureComponent {
type='button'
title={title}
aria-label={title}
className={`text-icon-button ${active ? 'active' : ''}`}
className={`text-icon-button ${active ? "active" : ""}`}
aria-expanded={active}
onClick={this.props.onClick}
aria-controls={ariaControls} style={iconStyle}
@@ -1,15 +1,15 @@
import PropTypes from 'prop-types';
import PropTypes from "prop-types";
import { FormattedMessage } from 'react-intl';
import { FormattedMessage } from "react-intl";
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 spring from 'react-motion/lib/spring';
import spring from "react-motion/lib/spring";
import { Icon } from 'mastodon/components/icon';
import { Icon } from "mastodon/components/icon";
import Motion from '../../ui/util/optional_motion';
import Motion from "../../ui/util/optional_motion";
export default class Upload extends ImmutablePureComponent {
@@ -25,12 +25,12 @@ export default class Upload extends ImmutablePureComponent {
handleUndoClick = e => {
e.stopPropagation();
this.props.onUndo(this.props.media.get('id'));
this.props.onUndo(this.props.media.get("id"));
};
handleFocalPointClick = e => {
e.stopPropagation();
this.props.onOpenFocalPoint(this.props.media.get('id'));
this.props.onOpenFocalPoint(this.props.media.get("id"));
};
render () {
@@ -40,8 +40,8 @@ export default class Upload extends ImmutablePureComponent {
return null;
}
const focusX = media.getIn(['meta', 'focus', 'x']);
const focusY = media.getIn(['meta', 'focus', 'y']);
const focusX = media.getIn(["meta", "focus", "x"]);
const focusY = media.getIn(["meta", "focus", "y"]);
const x = ((focusX / 2) + .5) * 100;
const y = ((focusY / -2) + .5) * 100;
@@ -49,13 +49,13 @@ export default class Upload extends ImmutablePureComponent {
<div className='compose-form__upload'>
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
{({ scale }) => (
<div className='compose-form__upload-thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: `url(${media.get('preview_url')})`, backgroundPosition: `${x}% ${y}%` }}>
<div className='compose-form__upload-thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: `url(${media.get("preview_url")})`, backgroundPosition: `${x}% ${y}%` }}>
<div className='compose-form__upload__actions'>
<button type='button' className='icon-button' onClick={this.handleUndoClick}><Icon id='times' /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button>
<button type='button' className='icon-button' onClick={this.handleFocalPointClick}><Icon id='pencil' /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button>
</div>
{(media.get('description') || '').length === 0 && (
{(media.get("description") || "").length === 0 && (
<div className='compose-form__upload__warning'>
<button type='button' className='icon-button' onClick={this.handleFocalPointClick}><Icon id='info-circle' /> <FormattedMessage id='upload_form.description_missing' defaultMessage='No description added' /></button>
</div>
@@ -1,20 +1,20 @@
import PropTypes from 'prop-types';
import PropTypes from "prop-types";
import { defineMessages, injectIntl } from 'react-intl';
import { defineMessages, injectIntl } from "react-intl";
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 { IconButton } from '../../../components/icon_button';
import { IconButton } from "../../../components/icon_button";
const messages = defineMessages({
upload: { id: 'upload_button.label', defaultMessage: 'Add images, a video or an audio file' },
upload: { id: "upload_button.label", defaultMessage: "Add images, a video or an audio file" },
});
const makeMapStateToProps = () => {
const mapStateToProps = state => ({
acceptContentTypes: state.getIn(['media_attachments', 'accept_content_types']),
acceptContentTypes: state.getIn(["media_attachments", "accept_content_types"]),
});
return mapStateToProps;
@@ -22,7 +22,7 @@ const makeMapStateToProps = () => {
const iconStyle = {
height: null,
lineHeight: '27px',
lineHeight: "27px",
};
class UploadButton extends ImmutablePureComponent {
@@ -64,16 +64,16 @@ class UploadButton extends ImmutablePureComponent {
<div className='compose-form__upload-button'>
<IconButton icon='paperclip' title={message} disabled={disabled} onClick={this.handleClick} className='compose-form__upload-button-icon' size={18} inverted style={iconStyle} />
<label>
<span style={{ display: 'none' }}>{message}</span>
<span style={{ display: "none" }}>{message}</span>
<input
key={resetFileKey}
ref={this.setRef}
type='file'
multiple
accept={acceptContentTypes.toArray().join(',')}
accept={acceptContentTypes.toArray().join(",")}
onChange={this.handleChange}
disabled={disabled}
style={{ display: 'none' }}
style={{ display: "none" }}
/>
</label>
</div>
@@ -1,9 +1,9 @@
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 SensitiveButtonContainer from '../containers/sensitive_button_container';
import UploadContainer from '../containers/upload_container';
import UploadProgressContainer from '../containers/upload_progress_container';
import SensitiveButtonContainer from "../containers/sensitive_button_container";
import UploadContainer from "../containers/upload_container";
import UploadProgressContainer from "../containers/upload_progress_container";
export default class UploadForm extends ImmutablePureComponent {
@@ -1,13 +1,13 @@
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 { Icon } from 'mastodon/components/icon';
import { Icon } from "mastodon/components/icon";
import Motion from '../../ui/util/optional_motion';
import Motion from "../../ui/util/optional_motion";
export default class UploadProgress 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 spring from 'react-motion/lib/spring';
import spring from "react-motion/lib/spring";
import Motion from '../../ui/util/optional_motion';
import Motion from "../../ui/util/optional_motion";
export default class Warning extends PureComponent {