[build] upgrade eslint to 9.37.0 (#88)
Co-authored-by: tobi <tobi.smethurst@protonmail.com> Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/88 Co-authored-by: Zoë Bijl <moiety@noreply.codeberg.org> Co-committed-by: Zoë Bijl <moiety@noreply.codeberg.org>
This commit is contained in:
@@ -1,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);
|
||||
|
||||
|
||||
+52
-50
@@ -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 {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user