[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,18 +40,18 @@ class ActionBar extends PureComponent {
let menu = [];
menu.push({ text: intl.formatMessage(messages.pins), to: '/pinned' });
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 'flavours/glitch/components/avatar';
import { DisplayName } from 'flavours/glitch/components/display_name';
import { Avatar } from "flavours/glitch/components/avatar";
import { DisplayName } from "flavours/glitch/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='account small' title={account.get('acct')}>
<div className='account small' title={account.get("acct")}>
<div className='account__avatar-wrapper'><Avatar account={account} size={24} /></div>
<DisplayName account={account} inline />
</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,40 +1,40 @@
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 { length } from 'stringz';
import { length } from "stringz";
import { maxChars } from 'flavours/glitch/initial_state';
import { isMobile } from 'flavours/glitch/is_mobile';
import { maxChars } from "flavours/glitch/initial_state";
import { isMobile } from "flavours/glitch/is_mobile";
import AutosuggestInput from '../../../components/autosuggest_input';
import AutosuggestTextarea from '../../../components/autosuggest_textarea';
import EmojiPickerDropdown from '../containers/emoji_picker_dropdown_container';
import OptionsContainer from '../containers/options_container';
import PollFormContainer from '../containers/poll_form_container';
import ReplyIndicatorContainer from '../containers/reply_indicator_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 EmojiPickerDropdown from "../containers/emoji_picker_dropdown_container";
import OptionsContainer from "../containers/options_container";
import PollFormContainer from "../containers/poll_form_container";
import ReplyIndicatorContainer from "../containers/reply_indicator_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 Publisher from './publisher';
import TextareaIcons from './textarea_icons';
import CharacterCounter from "./character_counter";
import Publisher from "./publisher";
import TextareaIcons from "./textarea_icons";
const messages = defineMessages({
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
placeholder: { id: "compose_form.placeholder", defaultMessage: "What is on your mind?" },
missingDescriptionMessage: {
id: 'confirmations.missing_media_description.message',
defaultMessage: 'At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.',
id: "confirmations.missing_media_description.message",
defaultMessage: "At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.",
},
missingDescriptionConfirm: {
id: 'confirmations.missing_media_description.confirm',
defaultMessage: 'Send anyway',
id: "confirmations.missing_media_description.confirm",
defaultMessage: "Send anyway",
},
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: '(Optional) post title / content warning' },
spoiler_placeholder: { id: "compose_form.spoiler_placeholder", defaultMessage: "(Optional) post title / content warning" },
});
class ComposeForm extends ImmutablePureComponent {
@@ -94,9 +94,9 @@ class ComposeForm extends ImmutablePureComponent {
getFulltextForCharacterCounting = () => {
return [
this.props.spoiler? this.props.spoilerText: '',
this.props.spoiler? this.props.spoilerText: "",
countableText(this.props.text),
].join('');
].join("");
};
canSubmit = () => {
@@ -126,9 +126,9 @@ class ComposeForm extends ImmutablePureComponent {
}
// Submit unless there are media with missing descriptions
if (mediaDescriptionConfirmation && onMediaDescriptionConfirm && media && media.some(item => !item.get('description'))) {
const firstWithoutDescription = media.find(item => !item.get('description'));
onMediaDescriptionConfirm(this.context.router ? this.context.router.history : null, firstWithoutDescription.get('id'), overriddenVisibility);
if (mediaDescriptionConfirmation && onMediaDescriptionConfirm && media && media.some(item => !item.get("description"))) {
const firstWithoutDescription = media.find(item => !item.get("description"));
onMediaDescriptionConfirm(this.context.router ? this.context.router.history : null, firstWithoutDescription.get("id"), overriddenVisibility);
} else if (onSubmit) {
if (onChangeVisibility && overriddenVisibility) {
onChangeVisibility(overriddenVisibility);
@@ -163,16 +163,16 @@ class ComposeForm extends ImmutablePureComponent {
const {
sideArm,
} = this.props;
this.handleSubmit(sideArm === 'none' ? null : sideArm);
this.handleSubmit(sideArm === "none" ? null : sideArm);
};
// Selects a suggestion from the autofill.
handleSuggestionSelected = (tokenStart, token, value) => {
this.props.onSuggestionSelected(tokenStart, token, value, ['text']);
this.props.onSuggestionSelected(tokenStart, token, value, ["text"]);
};
handleSpoilerSuggestionSelected = (tokenStart, token, value) => {
this.props.onSuggestionSelected(tokenStart, token, value, ['spoiler_text']);
this.props.onSuggestionSelected(tokenStart, token, value, ["spoiler_text"]);
};
handleKeyDown = (e) => {
@@ -242,15 +242,15 @@ class ComposeForm extends ImmutablePureComponent {
// Caret/selection handling.
if (focusDate !== prevProps.focusDate) {
switch (true) {
case preselectDate !== prevProps.preselectDate && this.props.isInReply && preselectOnReply:
selectionStart = text.search(/\s/) + 1;
selectionEnd = text.length;
break;
case !isNaN(caretPosition) && caretPosition !== null:
selectionStart = selectionEnd = caretPosition;
break;
default:
selectionStart = selectionEnd = text.length;
case preselectDate !== prevProps.preselectDate && this.props.isInReply && preselectOnReply:
selectionStart = text.search(/\s/) + 1;
selectionEnd = text.length;
break;
case !isNaN(caretPosition) && caretPosition !== null:
selectionStart = selectionEnd = caretPosition;
break;
default:
selectionStart = selectionEnd = text.length;
}
if (textarea) {
// Because of the wicg-inert polyfill, the activeElement may not be
@@ -259,7 +259,9 @@ class ComposeForm extends ImmutablePureComponent {
Promise.resolve().then(() => {
textarea.setSelectionRange(selectionStart, selectionEnd);
textarea.focus();
if (!singleColumn) textarea.scrollIntoView();
if (!singleColumn) {
textarea.scrollIntoView();
}
}).catch(console.error);
}
@@ -314,7 +316,7 @@ class ComposeForm extends ImmutablePureComponent {
<ReplyIndicatorContainer />
<div className={`spoiler-input ${spoiler ? 'spoiler-input--visible' : ''}`} ref={this.setRef} aria-hidden={!this.props.spoiler}>
<div className={`spoiler-input ${spoiler ? "spoiler-input--visible" : ""}`} ref={this.setRef} aria-hidden={!this.props.spoiler}>
<AutosuggestInput
placeholder={intl.formatMessage(messages.spoiler_placeholder)}
value={spoilerText}
@@ -326,7 +328,7 @@ class ComposeForm extends ImmutablePureComponent {
onSuggestionsFetchRequested={onFetchSuggestions}
onSuggestionsClearRequested={onClearSuggestions}
onSuggestionSelected={this.handleSpoilerSuggestionSelected}
searchTokens={[':']}
searchTokens={[":"]}
id='glitch.composer.spoiler.input'
className='spoiler-input__input'
lang={this.props.lang}
@@ -1,15 +1,15 @@
// Package imports.
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 Overlay from 'react-overlays/Overlay';
import Overlay from "react-overlays/Overlay";
// Components.
import { IconButton } from 'flavours/glitch/components/icon_button';
import { IconButton } from "flavours/glitch/components/icon_button";
import DropdownMenu from './dropdown_menu';
import DropdownMenu from "./dropdown_menu";
// The component.
export default class ComposerOptionsDropdown extends PureComponent {
@@ -41,7 +41,7 @@ export default class ComposerOptionsDropdown extends PureComponent {
state = {
open: false,
openedViaKeyboard: undefined,
placement: 'bottom',
placement: "bottom",
};
// Toggles opening and closing the dropdown.
@@ -62,15 +62,15 @@ export default class ComposerOptionsDropdown extends PureComponent {
if (open && this.activeElement) {
this.activeElement.focus({ preventScroll: true });
}
this.setState({ open: !open, openedViaKeyboard: type !== 'click' });
this.setState({ open: !open, openedViaKeyboard: type !== "click" });
}
};
handleKeyDown = (e) => {
switch (e.key) {
case 'Escape':
this.handleClose();
break;
case "Escape":
this.handleClose();
break;
}
};
@@ -82,21 +82,21 @@ export default class ComposerOptionsDropdown extends PureComponent {
handleButtonKeyDown = (e) => {
switch(e.key) {
case ' ':
case 'Enter':
this.handleMouseDown();
break;
case " ":
case "Enter":
this.handleMouseDown();
break;
}
};
handleKeyPress = (e) => {
switch(e.key) {
case ' ':
case 'Enter':
this.handleToggle(e);
e.stopPropagation();
e.preventDefault();
break;
case " ":
case "Enter":
this.handleToggle(e);
e.stopPropagation();
e.preventDefault();
break;
}
};
@@ -115,12 +115,14 @@ export default class ComposerOptionsDropdown extends PureComponent {
closeOnChange,
} = this.props;
const i = Number(e.currentTarget.getAttribute('data-index'));
const i = Number(e.currentTarget.getAttribute("data-index"));
const { name } = items[i];
e.preventDefault(); // Prevents focus from changing
if (closeOnChange) onModalClose();
if (closeOnChange) {
onModalClose();
}
onChange(name);
};
@@ -183,15 +185,15 @@ export default class ComposerOptionsDropdown extends PureComponent {
} = this.props;
const { open, placement } = this.state;
const active = value && items.findIndex(({ name }) => name === value) === (placement === 'bottom' ? 0 : (items.length - 1));
const active = value && items.findIndex(({ name }) => name === value) === (placement === "bottom" ? 0 : (items.length - 1));
return (
<div
className={classNames('privacy-dropdown', placement, { active: open })}
className={classNames("privacy-dropdown", placement, { active: open })}
onKeyDown={this.handleKeyDown}
ref={this.setTargetRef}
>
<div className={classNames('privacy-dropdown__value', { active })}>
<div className={classNames("privacy-dropdown__value", { active })}>
<IconButton
active={open}
className='privacy-dropdown__value-icon'
@@ -205,7 +207,7 @@ export default class ComposerOptionsDropdown extends PureComponent {
size={18}
style={{
height: null,
lineHeight: '27px',
lineHeight: "27px",
}}
title={title}
/>
@@ -218,7 +220,7 @@ export default class ComposerOptionsDropdown extends PureComponent {
flip
target={this.findTarget}
container={container}
popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}
popperConfig={{ strategy: "fixed", onFirstUpdate: this.handleOverlayEnter }}
>
{({ props, placement }) => (
<div {...props}>
@@ -1,13 +1,13 @@
// Package imports.
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 { supportsPassiveEvents } from 'detect-passive-events';
import { supportsPassiveEvents } from "detect-passive-events";
// Components.
import { Icon } from 'flavours/glitch/components/icon';
import { Icon } from "flavours/glitch/components/icon";
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
@@ -54,8 +54,8 @@ export default class ComposerOptionsDropdownContent extends PureComponent {
// On mounting, we add our listeners.
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);
if (this.focusedItem) {
this.focusedItem.focus({ preventScroll: true });
} else {
@@ -65,12 +65,12 @@ export default class ComposerOptionsDropdownContent extends PureComponent {
// On unmounting, we remove our listeners.
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);
}
handleClick = (e) => {
const i = Number(e.currentTarget.getAttribute('data-index'));
const i = Number(e.currentTarget.getAttribute("data-index"));
const {
onChange,
@@ -98,42 +98,42 @@ export default class ComposerOptionsDropdownContent extends PureComponent {
};
handleKeyDown = (e) => {
const index = Number(e.currentTarget.getAttribute('data-index'));
const index = Number(e.currentTarget.getAttribute("data-index"));
const { items } = this.props;
let element = null;
switch(e.key) {
case 'Escape':
this.props.onClose();
break;
case 'Enter':
case ' ':
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":
case " ":
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.handleChange(items[Number(element.getAttribute('data-index'))].name);
this.handleChange(items[Number(element.getAttribute("data-index"))].name);
e.preventDefault();
e.stopPropagation();
}
@@ -148,7 +148,7 @@ export default class ComposerOptionsDropdownContent extends PureComponent {
const active = (name === (this.props.value || this.state.value));
const computedClass = classNames('privacy-dropdown__option', { active });
const computedClass = classNames("privacy-dropdown__option", { active });
let contents = this.props.renderItemContents && this.props.renderItemContents(item, i);
@@ -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 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 { useSystemEmojiFont } from 'flavours/glitch/initial_state';
import { assetHost } from 'flavours/glitch/utils/config';
import { useSystemEmojiFont } from "flavours/glitch/initial_state";
import { assetHost } from "flavours/glitch/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
@@ -63,7 +63,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) {
@@ -85,13 +85,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 => {
@@ -102,7 +102,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 onClick={this.handleClick} data-index={1}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={1} backgroundImageFn={backgroundImageFn} native={useSystemEmojiFont} /></button>
<button onClick={this.handleClick} data-index={2}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={2} backgroundImageFn={backgroundImageFn} native={useSystemEmojiFont} /></button>
<button onClick={this.handleClick} data-index={3}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={3} backgroundImageFn={backgroundImageFn} native={useSystemEmojiFont} /></button>
@@ -183,23 +183,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 => {
@@ -261,21 +263,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}
@@ -357,7 +359,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 {
@@ -367,7 +369,7 @@ class EmojiPickerDropdown extends PureComponent {
};
handleKeyDown = e => {
if (e.key === 'Escape') {
if (e.key === "Escape") {
this.onHideDropdown();
}
};
@@ -389,13 +391,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,44 +1,44 @@
import PropTypes from 'prop-types';
import PropTypes from "prop-types";
import { injectIntl, defineMessages } from 'react-intl';
import { injectIntl, defineMessages } 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 { Icon } from 'flavours/glitch/components/icon';
import { signOutLink } from 'flavours/glitch/utils/backend_links';
import { conditionalRender } from 'flavours/glitch/utils/react_helpers';
import { Icon } from "flavours/glitch/components/icon";
import { signOutLink } from "flavours/glitch/utils/backend_links";
import { conditionalRender } from "flavours/glitch/utils/react_helpers";
const messages = defineMessages({
community: {
defaultMessage: 'Local timeline',
id: 'navigation_bar.community_timeline',
defaultMessage: "Local timeline",
id: "navigation_bar.community_timeline",
},
home_timeline: {
defaultMessage: 'Home',
id: 'tabs_bar.home',
defaultMessage: "Home",
id: "tabs_bar.home",
},
logout: {
defaultMessage: 'Logout',
id: 'navigation_bar.logout',
defaultMessage: "Logout",
id: "navigation_bar.logout",
},
notifications: {
defaultMessage: 'Notifications',
id: 'tabs_bar.notifications',
defaultMessage: "Notifications",
id: "tabs_bar.notifications",
},
public: {
defaultMessage: 'Federated timeline',
id: 'navigation_bar.public_timeline',
defaultMessage: "Federated timeline",
id: "navigation_bar.public_timeline",
},
settings: {
defaultMessage: 'App settings',
id: 'navigation_bar.app_settings',
defaultMessage: "App settings",
id: "navigation_bar.app_settings",
},
start: {
defaultMessage: 'Getting started',
id: 'getting_started.heading',
defaultMessage: "Getting started",
id: "getting_started.heading",
},
});
@@ -68,7 +68,7 @@ class Header extends ImmutablePureComponent {
// Only renders the component if the column isn't being shown.
const renderForColumn = conditionalRender.bind(null,
columnId => !columns || !columns.some(
column => column.get('id') === columnId,
column => column.get("id") === columnId,
),
);
@@ -80,14 +80,14 @@ class Header extends ImmutablePureComponent {
title={intl.formatMessage(messages.start)}
to='/getting-started'
><Icon id='asterisk' /></Link>
{renderForColumn('HOME', (
{renderForColumn("HOME", (
<Link
aria-label={intl.formatMessage(messages.home_timeline)}
title={intl.formatMessage(messages.home_timeline)}
to='/home'
><Icon id='home' /></Link>
))}
{renderForColumn('NOTIFICATIONS', (
{renderForColumn("NOTIFICATIONS", (
<Link
aria-label={intl.formatMessage(messages.notifications)}
title={intl.formatMessage(messages.notifications)}
@@ -99,14 +99,14 @@ class Header extends ImmutablePureComponent {
</span>
</Link>
))}
{renderForColumn('COMMUNITY', (
{renderForColumn("COMMUNITY", (
<Link
aria-label={intl.formatMessage(messages.community)}
title={intl.formatMessage(messages.community)}
to='/public/local'
><Icon id='users' /></Link>
))}
{renderForColumn('PUBLIC', (
{renderForColumn("PUBLIC", (
<Link
aria-label={intl.formatMessage(messages.public)}
title={intl.formatMessage(messages.public)}
@@ -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 'flavours/glitch/initial_state';
import { loupeIcon, deleteIcon } from 'flavours/glitch/utils/icons';
import { languages as preloadedLanguages } from "flavours/glitch/initial_state";
import { loupeIcon, deleteIcon } from "flavours/glitch/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,14 +1,14 @@
import PropTypes from 'prop-types';
import PropTypes from "prop-types";
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 Permalink from 'flavours/glitch/components/permalink';
// eslint-disable-next-line import/no-restricted-paths
import initialState from 'mastodon/initial_state';
import { Avatar } from "flavours/glitch/components/avatar";
import Permalink from "flavours/glitch/components/permalink";
import initialState from "mastodon/initial_state";
import ActionBar from './action_bar';
import ActionBar from "./action_bar";
export default class NavigationBar extends ImmutablePureComponent {
@@ -20,15 +20,15 @@ export default class NavigationBar extends ImmutablePureComponent {
render () {
return (
<div className='navigation-bar'>
<Permalink className='avatar' href={this.props.account.get('url')} to={`/@${this.props.account.get('acct')}`}>
<span style={{ display: 'none' }}>{this.props.account.get('acct')}</span>
<Permalink className='avatar' href={this.props.account.get("url")} to={`/@${this.props.account.get("acct")}`}>
<span style={{ display: "none" }}>{this.props.account.get("acct")}</span>
<Avatar account={this.props.account} size={48} />
</Permalink>
<div className='navigation-bar__profile'>
<div>{this.props.account.get('display_name')}</div>
<Permalink className='acct' href={this.props.account.get('url')} to={`/@${this.props.account.get('acct')}`}>
<strong>@{this.props.account.get('acct')}</strong>
<div>{this.props.account.get("display_name")}</div>
<Permalink className='acct' href={this.props.account.get("url")} to={`/@${this.props.account.get("acct")}`}>
<strong>@{this.props.account.get("acct")}</strong>
<span>@{initialState.meta.domain}</span>
</Permalink>
</div>
@@ -1,24 +1,24 @@
// Package imports.
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 Toggle from 'react-toggle';
import Toggle from "react-toggle";
// Components.
import { IconButton } from 'flavours/glitch/components/icon_button';
import { pollLimits } from 'flavours/glitch/initial_state';
import { IconButton } from "flavours/glitch/components/icon_button";
import { pollLimits } from "flavours/glitch/initial_state";
import DropdownContainer from '../containers/dropdown_container';
import LanguageDropdown from '../containers/language_dropdown_container';
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
import DropdownContainer from "../containers/dropdown_container";
import LanguageDropdown from "../containers/language_dropdown_container";
import PrivacyDropdownContainer from "../containers/privacy_dropdown_container";
import TextIconButton from './text_icon_button';
import TextIconButton from "./text_icon_button";
@@ -27,69 +27,69 @@ import TextIconButton from './text_icon_button';
// Messages.
const messages = defineMessages({
advanced_options_icon_title: {
defaultMessage: 'Advanced options',
id: 'advanced_options.icon_title',
defaultMessage: "Advanced options",
id: "advanced_options.icon_title",
},
attach: {
defaultMessage: 'Attach...',
id: 'compose.attach',
defaultMessage: "Attach...",
id: "compose.attach",
},
content_type: {
defaultMessage: 'Content type',
id: 'content-type.change',
defaultMessage: "Content type",
id: "content-type.change",
},
doodle: {
defaultMessage: 'Draw something',
id: 'compose.attach.doodle',
defaultMessage: "Draw something",
id: "compose.attach.doodle",
},
html: {
defaultMessage: 'HTML',
id: 'compose.content-type.html',
defaultMessage: "HTML",
id: "compose.content-type.html",
},
local_only_long: {
defaultMessage: 'Do not post to other instances',
id: 'advanced_options.local-only.long',
defaultMessage: "Do not post to other instances",
id: "advanced_options.local-only.long",
},
local_only_short: {
defaultMessage: 'Local-only',
id: 'advanced_options.local-only.short',
defaultMessage: "Local-only",
id: "advanced_options.local-only.short",
},
markdown: {
defaultMessage: 'Markdown',
id: 'compose.content-type.markdown',
defaultMessage: "Markdown",
id: "compose.content-type.markdown",
},
plain: {
defaultMessage: 'Plain text',
id: 'compose.content-type.plain',
defaultMessage: "Plain text",
id: "compose.content-type.plain",
},
spoiler: {
defaultMessage: 'Hide text behind warning',
id: 'compose_form.spoiler',
defaultMessage: "Hide text behind warning",
id: "compose_form.spoiler",
},
threaded_mode_long: {
defaultMessage: 'Automatically opens a reply on posting',
id: 'advanced_options.threaded_mode.long',
defaultMessage: "Automatically opens a reply on posting",
id: "advanced_options.threaded_mode.long",
},
threaded_mode_short: {
defaultMessage: 'Threaded mode',
id: 'advanced_options.threaded_mode.short',
defaultMessage: "Threaded mode",
id: "advanced_options.threaded_mode.short",
},
upload: {
defaultMessage: 'Upload a file',
id: 'compose.attach.upload',
defaultMessage: "Upload a file",
id: "compose.attach.upload",
},
add_poll: {
defaultMessage: 'Add a poll',
id: 'poll_button.add_poll',
defaultMessage: "Add a poll",
id: "poll_button.add_poll",
},
remove_poll: {
defaultMessage: 'Remove poll',
id: 'poll_button.remove_poll',
defaultMessage: "Remove poll",
id: "poll_button.remove_poll",
},
});
const mapStateToProps = (state, { name }) => ({
checked: state.getIn(['compose', 'advanced_options', name]),
checked: state.getIn(["compose", "advanced_options", name]),
});
class ToggleOptionImpl extends ImmutablePureComponent {
@@ -161,16 +161,16 @@ class ComposerOptions extends ImmutablePureComponent {
// We switch over the name of the option.
switch (name) {
case 'upload':
if (fileElement) {
fileElement.click();
}
return;
case 'doodle':
if (onDoodleOpen) {
onDoodleOpen();
}
return;
case "upload":
if (fileElement) {
fileElement.click();
}
return;
case "doodle":
if (onDoodleOpen) {
onDoodleOpen();
}
return;
}
};
@@ -209,13 +209,13 @@ class ComposerOptions extends ImmutablePureComponent {
const contentTypeItems = {
plain: {
icon: 'file-text',
name: 'text/plain',
icon: "file-text",
name: "text/plain",
text: formatMessage(messages.plain),
},
markdown: {
icon: 'arrow-circle-down',
name: 'text/markdown',
icon: "arrow-circle-down",
name: "text/markdown",
text: formatMessage(messages.markdown),
},
};
@@ -231,20 +231,20 @@ class ComposerOptions extends ImmutablePureComponent {
ref={this.handleRefFileElement}
type='file'
multiple
style={{ display: 'none' }}
style={{ display: "none" }}
/>
<DropdownContainer
disabled={disabled || !allowMedia}
icon='paperclip'
items={[
{
icon: 'cloud-upload',
name: 'upload',
icon: "cloud-upload",
name: "upload",
text: formatMessage(messages.upload),
},
{
icon: 'paint-brush',
name: 'doodle',
icon: "paint-brush",
name: "doodle",
text: formatMessage(messages.doodle),
},
]}
@@ -271,7 +271,7 @@ class ComposerOptions extends ImmutablePureComponent {
{showContentTypeChoice && (
<DropdownContainer
disabled={disabled}
icon={(contentTypeItems[contentType.split('/')[1]] || {}).icon}
icon={(contentTypeItems[contentType.split("/")[1]] || {}).icon}
items={[
contentTypeItems.plain,
contentTypeItems.markdown,
@@ -297,12 +297,12 @@ class ComposerOptions extends ImmutablePureComponent {
items={advancedOptions ? [
{
meta: formatMessage(messages.local_only_long),
name: 'do_not_federate',
name: "do_not_federate",
text: formatMessage(messages.local_only_short),
},
{
meta: formatMessage(messages.threaded_mode_long),
name: 'threaded_mode',
name: "threaded_mode",
text: formatMessage(messages.threaded_mode_short),
},
] : null}
@@ -1,28 +1,28 @@
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 'flavours/glitch/components/autosuggest_input';
import { Icon } from 'flavours/glitch/components/icon';
import { IconButton } from 'flavours/glitch/components/icon_button';
import { pollLimits } from 'flavours/glitch/initial_state';
import AutosuggestInput from "flavours/glitch/components/autosuggest_input";
import { Icon } from "flavours/glitch/components/icon";
import { IconButton } from "flavours/glitch/components/icon_button";
import { pollLimits } from "flavours/glitch/initial_state";
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' },
single_choice: { id: 'compose_form.poll.single_choice', defaultMessage: 'Allow one choice' },
multiple_choices: { id: 'compose_form.poll.multiple_choices', defaultMessage: 'Allow multiple choices' },
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" },
single_choice: { id: "compose_form.poll.single_choice", defaultMessage: "Allow one choice" },
multiple_choices: { id: "compose_form.poll.multiple_choices", defaultMessage: "Allow multiple choices" },
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 {
@@ -59,7 +59,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 () {
@@ -68,7 +68,7 @@ class OptionIntl extends PureComponent {
return (
<li>
<label className='poll__option editable'>
<span className={classNames('poll__input', { checkbox: isPollMultiple })} />
<span className={classNames("poll__input", { checkbox: isPollMultiple })} />
<AutosuggestInput
placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })}
@@ -81,7 +81,7 @@ class OptionIntl extends PureComponent {
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSuggestionSelected}
searchTokens={[':']}
searchTokens={[":"]}
autoFocus={autoFocus}
/>
</label>
@@ -116,7 +116,7 @@ class PollForm extends ImmutablePureComponent {
};
handleAddOption = () => {
this.props.onAddOption('');
this.props.onAddOption("");
};
handleSelectDuration = e => {
@@ -124,7 +124,7 @@ class PollForm extends ImmutablePureComponent {
};
handleSelectMultiple = e => {
this.props.onChangeSettings(this.props.expiresIn, e.target.value === 'true');
this.props.onChangeSettings(this.props.expiresIn, e.target.value === "true");
};
render () {
@@ -134,7 +134,7 @@ class PollForm extends ImmutablePureComponent {
return null;
}
const autoFocusIndex = options.indexOf('');
const autoFocusIndex = options.indexOf("");
return (
<div className='compose-form__poll-wrapper'>
@@ -142,7 +142,7 @@ class PollForm extends ImmutablePureComponent {
{options.map((title, i) => <Option title={title} lang={lang} key={i} index={i} onChange={onChangeOption} onRemove={onRemoveOption} isPollMultiple={isMultiple} autoFocus={i === autoFocusIndex} {...other} />)}
{options.size < pollLimits.max_options && (
<label className='poll__text editable'>
<span className={classNames('poll__input')} style={{ opacity: 0 }} />
<span className={classNames("poll__input")} style={{ opacity: 0 }} />
<button className='button button-secondary' onClick={this.handleAddOption}><Icon id='plus' /> <FormattedMessage {...messages.add_option} /></button>
</label>
)}
@@ -150,7 +150,7 @@ class PollForm extends ImmutablePureComponent {
<div className='poll__footer'>
{/* eslint-disable-next-line jsx-a11y/no-onchange */}
<select value={isMultiple ? 'true' : 'false'} onChange={this.handleSelectMultiple}>
<select value={isMultiple ? "true" : "false"} onChange={this.handleSelectMultiple}>
<option value='false'>{intl.formatMessage(messages.single_choice)}</option>
<option value='true'>{intl.formatMessage(messages.multiple_choices)}</option>
</select>
@@ -1,20 +1,20 @@
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 Dropdown from './dropdown';
import Dropdown from "./dropdown";
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" },
});
class PrivacyDropdown extends PureComponent {
@@ -38,27 +38,27 @@ class PrivacyDropdown extends PureComponent {
// dropdown icon later.
const privacyItems = {
direct: {
icon: 'envelope',
icon: "envelope",
meta: formatMessage(messages.direct_long),
name: 'direct',
name: "direct",
text: formatMessage(messages.direct_short),
},
private: {
icon: 'lock',
icon: "lock",
meta: formatMessage(messages.private_long),
name: 'private',
name: "private",
text: formatMessage(messages.private_short),
},
public: {
icon: 'globe',
icon: "globe",
meta: formatMessage(messages.public_long),
name: 'public',
name: "public",
text: formatMessage(messages.public_short),
},
unlisted: {
icon: 'unlock',
icon: "unlock",
meta: formatMessage(messages.unlisted_long),
name: 'unlisted',
name: "unlisted",
text: formatMessage(messages.unlisted_short),
},
};
@@ -1,31 +1,31 @@
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 ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePureComponent from "react-immutable-pure-component";
import { length } from 'stringz';
import { length } from "stringz";
import Button from 'flavours/glitch/components/button';
import { Icon } from 'flavours/glitch/components/icon';
import { maxChars } from 'flavours/glitch/initial_state';
import Button from "flavours/glitch/components/button";
import { Icon } from "flavours/glitch/components/icon";
import { maxChars } from "flavours/glitch/initial_state";
const messages = defineMessages({
publish: {
defaultMessage: 'Promulgate',
id: 'compose_form.publish',
defaultMessage: "Promulgate",
id: "compose_form.publish",
},
publishLoud: {
defaultMessage: '{publish}!',
id: 'compose_form.publish_loud',
defaultMessage: "{publish}!",
id: "compose_form.publish_loud",
},
saveChanges: { id: 'compose_form.save_changes', defaultMessage: 'Save changes' },
public: { id: 'privacy.public.short', defaultMessage: 'Public' },
unlisted: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
private: { id: 'privacy.private.short', defaultMessage: 'Followers only' },
direct: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
saveChanges: { id: "compose_form.save_changes", defaultMessage: "Save changes" },
public: { id: "privacy.public.short", defaultMessage: "Public" },
unlisted: { id: "privacy.unlisted.short", defaultMessage: "Unlisted" },
private: { id: "privacy.private.short", defaultMessage: "Followers only" },
direct: { id: "privacy.direct.short", defaultMessage: "Mentioned people only" },
});
class Publisher extends ImmutablePureComponent {
@@ -36,8 +36,8 @@ class Publisher extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
onSecondarySubmit: PropTypes.func,
onSubmit: PropTypes.func,
privacy: PropTypes.oneOf(['direct', 'private', 'unlisted', 'public']),
sideArm: PropTypes.oneOf(['none', 'direct', 'private', 'unlisted', 'public']),
privacy: PropTypes.oneOf(["direct", "private", "unlisted", "public"]),
sideArm: PropTypes.oneOf(["none", "direct", "private", "unlisted", "public"]),
isEditing: PropTypes.bool,
};
@@ -48,18 +48,18 @@ class Publisher extends ImmutablePureComponent {
render () {
const { countText, disabled, intl, onSecondarySubmit, privacy, sideArm, isEditing } = this.props;
const diff = maxChars - length(countText || '');
const computedClass = classNames('compose-form__publish', {
const diff = maxChars - length(countText || "");
const computedClass = classNames("compose-form__publish", {
disabled: disabled,
over: diff < 0,
});
const privacyIcons = { direct: 'envelope', private: 'lock', public: 'globe', unlisted: 'unlock' };
const privacyIcons = { direct: "envelope", private: "lock", public: "globe", unlisted: "unlock" };
let publishText;
if (isEditing) {
publishText = intl.formatMessage(messages.saveChanges);
} else if (privacy === 'private' || privacy === 'direct') {
} else if (privacy === "private" || privacy === "direct") {
const iconId = privacyIcons[privacy];
publishText = (
<span>
@@ -67,7 +67,7 @@ class Publisher extends ImmutablePureComponent {
</span>
);
} else {
publishText = privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
publishText = privacy !== "unlisted" ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
}
const privacyNames = {
@@ -79,7 +79,7 @@ class Publisher extends ImmutablePureComponent {
return (
<div className={computedClass}>
{sideArm && !isEditing && sideArm !== 'none' ? (
{sideArm && !isEditing && sideArm !== "none" ? (
<div className='compose-form__publish-button-wrapper'>
<Button
className='side_arm'
@@ -1,20 +1,20 @@
// Package imports.
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";
// Components.
import AttachmentList from 'flavours/glitch/components/attachment_list';
import { IconButton } from 'flavours/glitch/components/icon_button';
import AccountContainer from 'flavours/glitch/containers/account_container';
import AttachmentList from "flavours/glitch/components/attachment_list";
import { IconButton } from "flavours/glitch/components/icon_button";
import AccountContainer from "flavours/glitch/containers/account_container";
// Messages.
const messages = defineMessages({
cancel: {
defaultMessage: 'Cancel',
id: 'reply_indicator.cancel',
defaultMessage: "Cancel",
id: "reply_indicator.cancel",
},
});
@@ -42,9 +42,9 @@ class ReplyIndicator extends ImmutablePureComponent {
return null;
}
const account = status.get('account');
const content = status.get('content');
const attachments = status.get('media_attachments');
const account = status.get("account");
const content = status.get("content");
const attachments = status.get("media_attachments");
// The result.
return (
@@ -66,7 +66,7 @@ class ReplyIndicator extends ImmutablePureComponent {
</header>
<div
className='reply-indicator__content translate'
dangerouslySetInnerHTML={{ __html: content || '' }}
dangerouslySetInnerHTML={{ __html: content || "" }}
/>
{attachments.size > 0 && (
<AttachmentList
@@ -1,31 +1,31 @@
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 'flavours/glitch/components/icon';
import { domain, searchEnabled } from 'flavours/glitch/initial_state';
import { focusRoot } from 'flavours/glitch/utils/dom_helpers';
import { HASHTAG_REGEX } from 'flavours/glitch/utils/hashtags';
import { Icon } from "flavours/glitch/components/icon";
import { domain, searchEnabled } from "flavours/glitch/initial_state";
import { focusRoot } from "flavours/glitch/utils/dom_helpers";
import { HASHTAG_REGEX } from "flavours/glitch/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");
}
};
@@ -59,14 +59,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 => {
@@ -120,48 +136,48 @@ class Search extends PureComponent {
const options = searchEnabled ? this._getOptions().concat(this.defaultOptions) : this._getOptions();
switch(e.key) {
case 'Escape':
e.preventDefault();
case "Escape":
e.preventDefault();
focusRoot();
focusRoot();
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;
}
};
@@ -173,10 +189,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();
};
@@ -184,10 +200,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();
};
@@ -200,24 +216,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();
@@ -226,19 +242,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}`);
@@ -256,7 +272,7 @@ class Search extends PureComponent {
}
if (openInRoute) {
router.history.push('/search');
router.history.push("/search");
}
this._unfocus();
@@ -288,34 +304,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 });
}
}
@@ -330,14 +346,14 @@ 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'
type='text'
placeholder={intl.formatMessage(signedIn ? messages.placeholderSignedIn : messages.placeholder)}
aria-label={intl.formatMessage(signedIn ? messages.placeholderSignedIn : messages.placeholder)}
value={value || ''}
value={value || ""}
onChange={this.handleChange}
onKeyDown={this.handleKeyDown}
onFocus={this.handleFocus}
@@ -345,8 +361,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' : ''} />
<Icon id='search' className={hasValue ? "" : "active"} />
<Icon id='times-circle' className={hasValue ? "active" : ""} />
</div>
<div className='search__popout'>
{options.length === 0 && (
@@ -355,7 +371,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>
@@ -373,7 +389,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>
))}
@@ -386,7 +402,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,16 +1,16 @@
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 { ImmutableHashtag as Hashtag } from 'flavours/glitch/components/hashtag';
import { Icon } from 'flavours/glitch/components/icon';
import { LoadMore } from 'flavours/glitch/components/load_more';
import AccountContainer from 'flavours/glitch/containers/account_container';
import StatusContainer from 'flavours/glitch/containers/status_container';
import { SearchSection } from 'flavours/glitch/features/explore/components/search_section';
import { ImmutableHashtag as Hashtag } from "flavours/glitch/components/hashtag";
import { Icon } from "flavours/glitch/components/icon";
import { LoadMore } from "flavours/glitch/components/load_more";
import AccountContainer from "flavours/glitch/containers/account_container";
import StatusContainer from "flavours/glitch/containers/status_container";
import { SearchSection } from "flavours/glitch/features/explore/components/search_section";
const INITIAL_PAGE_LIMIT = 10;
@@ -30,40 +30,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`,
};
@@ -24,7 +24,7 @@ export default class TextIconButton extends PureComponent {
<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}
@@ -1,30 +1,30 @@
// Package imports.
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";
// Components.
import { Icon } from 'flavours/glitch/components/icon';
import { Icon } from "flavours/glitch/components/icon";
// Messages.
const messages = defineMessages({
localOnly: {
defaultMessage: 'This post is local-only',
id: 'advanced_options.local-only.tooltip',
defaultMessage: "This post is local-only",
id: "advanced_options.local-only.tooltip",
},
threadedMode: {
defaultMessage: 'Threaded mode enabled',
id: 'advanced_options.threaded_mode.tooltip',
defaultMessage: "Threaded mode enabled",
id: "advanced_options.threaded_mode.tooltip",
},
});
// We use an array of tuples here instead of an object because it
// preserves order.
const iconMap = [
['do_not_federate', 'home', messages.localOnly],
['threaded_mode', 'comments', messages.threadedMode],
["do_not_federate", "home", messages.localOnly],
["threaded_mode", "comments", messages.threadedMode],
];
class TextareaIcons extends ImmutablePureComponent {
@@ -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 'flavours/glitch/components/icon';
import { Icon } from "flavours/glitch/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,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 'flavours/glitch/components/icon';
import { Icon } from "flavours/glitch/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 {