From 924ffe81d477a8cf890c8117efb94b908760bccc Mon Sep 17 00:00:00 2001 From: kibigo! Date: Sat, 23 Dec 2017 22:16:45 -0800 Subject: [PATCH 1/7] WIPgit status Refactor; ed. --- .../flavours/glitch/actions/compose.js | 17 +- .../flavours/glitch/components/account.js | 26 +- .../glitch/components/autosuggest_emoji.js | 42 -- .../glitch/components/autosuggest_textarea.js | 223 --------- .../flavours/glitch/components/icon.js | 26 ++ .../components/text_icon_button.js | 0 .../compose/components/advanced_options.js | 62 --- .../components/advanced_options_toggle.js | 35 -- .../compose/components/attach_options.js | 131 ------ .../compose/components/autosuggest_account.js | 24 - .../compose/components/character_counter.js | 25 - .../compose/components/compose_form.js | 286 ------------ .../features/compose/components/dropdown.js | 77 --- .../compose/components/privacy_dropdown.js | 200 -------- .../compose/components/reply_indicator.js | 67 --- .../features/compose/components/upload.js | 96 ---- .../compose/components/upload_button.js | 77 --- .../compose/components/upload_form.js | 29 -- .../compose/components/upload_progress.js | 42 -- .../features/compose/components/warning.js | 26 -- .../containers/advanced_options_container.js | 20 - .../autosuggest_account_container.js | 15 - .../containers/compose_form_container.js | 71 --- .../emoji_picker_dropdown_container.js | 82 ---- .../containers/privacy_dropdown_container.js | 24 - .../containers/reply_indicator_container.js | 24 - .../containers/sensitive_button_container.js | 71 --- .../containers/spoiler_button_container.js | 25 - .../containers/upload_button_container.js | 18 - .../compose/containers/upload_container.js | 21 - .../containers/upload_form_container.js | 8 - .../containers/upload_progress_container.js | 9 - .../compose/containers/warning_container.js | 24 - .../flavours/glitch/features/compose/index.js | 126 ----- .../glitch/features/composer/index.js | 440 ++++++++++++++++++ .../composer/options/dropdown/index.js | 243 ++++++++++ .../composer/options/dropdown/item/index.js | 126 +++++ .../glitch/features/composer/options/index.js | 321 +++++++++++++ .../features/composer/publisher/index.js | 119 +++++ .../glitch/features/composer/reply/index.js | 106 +++++ .../glitch/features/composer/spoiler/index.js | 92 ++++ .../features/composer/textarea/index.js | 297 ++++++++++++ .../composer/textarea/suggestions/index.js | 41 ++ .../textarea/suggestions/item/index.js | 101 ++++ .../features/composer/upload_form/index.js | 54 +++ .../composer/upload_form/item/index.js | 176 +++++++ .../composer/upload_form/progress/index.js | 52 +++ .../glitch/features/composer/warning/index.js | 54 +++ .../components/navigation_bar.js | 0 .../{compose => drawer}/components/search.js | 0 .../components/search_results.js | 0 .../containers/navigation_container.js | 0 .../containers/search_container.js | 0 .../containers/search_results_container.js | 0 .../flavours/glitch/features/drawer/index.js | 198 ++++++++ .../index.js} | 80 ++++ .../features/standalone/compose/index.js | 4 +- .../flavours/glitch/reducers/compose.js | 2 +- .../glitch/styles/components/compose.scss | 0 .../glitch/styles/components/drawer.scss | 0 .../flavours/glitch/util/dom_helpers.js | 6 + .../flavours/glitch/util/initial_state.js | 1 + .../flavours/glitch/util/react_helpers.js | 21 + .../flavours/glitch/util/redux_helpers.js | 7 + 64 files changed, 2588 insertions(+), 2002 deletions(-) delete mode 100644 app/javascript/flavours/glitch/components/autosuggest_emoji.js delete mode 100644 app/javascript/flavours/glitch/components/autosuggest_textarea.js create mode 100644 app/javascript/flavours/glitch/components/icon.js rename app/javascript/flavours/glitch/{features/compose => }/components/text_icon_button.js (100%) delete mode 100644 app/javascript/flavours/glitch/features/compose/components/advanced_options.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/advanced_options_toggle.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/attach_options.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/autosuggest_account.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/character_counter.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/compose_form.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/dropdown.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/reply_indicator.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/upload.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/upload_button.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/upload_form.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/upload_progress.js delete mode 100644 app/javascript/flavours/glitch/features/compose/components/warning.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/advanced_options_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/autosuggest_account_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/emoji_picker_dropdown_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/privacy_dropdown_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/reply_indicator_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/sensitive_button_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/spoiler_button_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/upload_button_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/upload_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/upload_form_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/upload_progress_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/warning_container.js delete mode 100644 app/javascript/flavours/glitch/features/compose/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/options/dropdown/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/options/dropdown/item/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/options/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/publisher/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/reply/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/spoiler/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/textarea/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/textarea/suggestions/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/textarea/suggestions/item/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/upload_form/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/upload_form/item/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/upload_form/progress/index.js create mode 100644 app/javascript/flavours/glitch/features/composer/warning/index.js rename app/javascript/flavours/glitch/features/{compose => drawer}/components/navigation_bar.js (100%) rename app/javascript/flavours/glitch/features/{compose => drawer}/components/search.js (100%) rename app/javascript/flavours/glitch/features/{compose => drawer}/components/search_results.js (100%) rename app/javascript/flavours/glitch/features/{compose => drawer}/containers/navigation_container.js (100%) rename app/javascript/flavours/glitch/features/{compose => drawer}/containers/search_container.js (100%) rename app/javascript/flavours/glitch/features/{compose => drawer}/containers/search_results_container.js (100%) create mode 100644 app/javascript/flavours/glitch/features/drawer/index.js rename app/javascript/flavours/glitch/features/{compose/components/emoji_picker_dropdown.js => emoji_picker/index.js} (85%) create mode 100644 app/javascript/flavours/glitch/styles/components/compose.scss create mode 100644 app/javascript/flavours/glitch/styles/components/drawer.scss create mode 100644 app/javascript/flavours/glitch/util/dom_helpers.js create mode 100644 app/javascript/flavours/glitch/util/react_helpers.js create mode 100644 app/javascript/flavours/glitch/util/redux_helpers.js diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js index 32746f27b6..d87786008c 100644 --- a/app/javascript/flavours/glitch/actions/compose.js +++ b/app/javascript/flavours/glitch/actions/compose.js @@ -316,21 +316,14 @@ export function readyComposeSuggestionsAccounts(token, accounts) { export function selectComposeSuggestion(position, token, suggestion) { return (dispatch, getState) => { - let completion, startPosition; - - if (typeof suggestion === 'object' && suggestion.id) { - completion = suggestion.native || suggestion.colons; - startPosition = position - 1; - - dispatch(useEmoji(suggestion)); - } else { - completion = getState().getIn(['accounts', suggestion, 'acct']); - startPosition = position; - } + const completion = typeof suggestion === 'object' && suggestion.id ? ( + dispatch(useEmoji(suggestion)), + suggestion.native || suggestion.colons + ) : '@' + getState().getIn(['accounts', suggestion, 'acct']); dispatch({ type: COMPOSE_SUGGESTION_SELECT, - position: startPosition, + position, token, completion, }); diff --git a/app/javascript/flavours/glitch/components/account.js b/app/javascript/flavours/glitch/components/account.js index a1f0754919..ced18b3481 100644 --- a/app/javascript/flavours/glitch/components/account.js +++ b/app/javascript/flavours/glitch/components/account.js @@ -30,6 +30,7 @@ export default class Account extends ImmutablePureComponent { onMuteNotifications: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, hidden: PropTypes.bool, + small: PropTypes.bool, }; handleFollow = () => { @@ -53,7 +54,12 @@ export default class Account extends ImmutablePureComponent { } render () { - const { account, intl, hidden } = this.props; + const { + account, + hidden, + intl, + small, + } = this.props; if (!account) { return
; @@ -70,7 +76,7 @@ export default class Account extends ImmutablePureComponent { let buttons; - if (account.get('id') !== me && account.get('relationship', null) !== null) { + if (account.get('id') !== me && !small && account.get('relationship', null) !== null) { const following = account.getIn(['relationship', 'following']); const requested = account.getIn(['relationship', 'requested']); const blocking = account.getIn(['relationship', 'blocking']); @@ -98,17 +104,23 @@ export default class Account extends ImmutablePureComponent { } } - return ( + return small ? ( +
+
+ +
+ ) : (
- -
- {buttons} -
+ {buttons ? +
+ {buttons} +
+ : null}
); diff --git a/app/javascript/flavours/glitch/components/autosuggest_emoji.js b/app/javascript/flavours/glitch/components/autosuggest_emoji.js deleted file mode 100644 index 79e113d9cf..0000000000 --- a/app/javascript/flavours/glitch/components/autosuggest_emoji.js +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import unicodeMapping from 'flavours/glitch/util/emoji/emoji_unicode_mapping_light'; - -const assetHost = process.env.CDN_HOST || ''; - -export default class AutosuggestEmoji extends React.PureComponent { - - static propTypes = { - emoji: PropTypes.object.isRequired, - }; - - render () { - const { emoji } = this.props; - let url; - - if (emoji.custom) { - url = emoji.imageUrl; - } else { - const mapping = unicodeMapping[emoji.native] || unicodeMapping[emoji.native.replace(/\uFE0F$/, '')]; - - if (!mapping) { - return null; - } - - url = `${assetHost}/emoji/${mapping.filename}.svg`; - } - - return ( -
- {emoji.native - - {emoji.colons} -
- ); - } - -} diff --git a/app/javascript/flavours/glitch/components/autosuggest_textarea.js b/app/javascript/flavours/glitch/components/autosuggest_textarea.js deleted file mode 100644 index a29b2c9c57..0000000000 --- a/app/javascript/flavours/glitch/components/autosuggest_textarea.js +++ /dev/null @@ -1,223 +0,0 @@ -import React from 'react'; -import AutosuggestAccountContainer from 'flavours/glitch/features/compose/containers/autosuggest_account_container'; -import AutosuggestEmoji from './autosuggest_emoji'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import PropTypes from 'prop-types'; -import { isRtl } from 'flavours/glitch/util/rtl'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import Textarea from 'react-textarea-autosize'; -import classNames from 'classnames'; - -const textAtCursorMatchesToken = (str, caretPosition) => { - let word; - - let left = str.slice(0, caretPosition).search(/[^\s\u200B]+$/); - let right = str.slice(caretPosition).search(/[\s\u200B]/); - - if (right < 0) { - word = str.slice(left); - } else { - word = str.slice(left, right + caretPosition); - } - - if (!word || word.trim().length < 3 || ['@', ':'].indexOf(word[0]) === -1) { - return [null, null]; - } - - word = word.trim().toLowerCase(); - - if (word.length > 0) { - return [left + 1, word]; - } else { - return [null, null]; - } -}; - -export default class AutosuggestTextarea extends ImmutablePureComponent { - - static propTypes = { - value: PropTypes.string, - suggestions: ImmutablePropTypes.list, - disabled: PropTypes.bool, - placeholder: PropTypes.string, - onSuggestionSelected: PropTypes.func.isRequired, - onSuggestionsClearRequested: PropTypes.func.isRequired, - onSuggestionsFetchRequested: PropTypes.func.isRequired, - onChange: PropTypes.func.isRequired, - onKeyUp: PropTypes.func, - onKeyDown: PropTypes.func, - onPaste: PropTypes.func.isRequired, - autoFocus: PropTypes.bool, - }; - - static defaultProps = { - autoFocus: true, - }; - - state = { - suggestionsHidden: false, - selectedSuggestion: 0, - lastToken: null, - tokenStart: 0, - }; - - onChange = (e) => { - const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart); - - if (token !== null && this.state.lastToken !== token) { - this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart }); - this.props.onSuggestionsFetchRequested(token); - } else if (token === null) { - this.setState({ lastToken: null }); - this.props.onSuggestionsClearRequested(); - } - - this.props.onChange(e); - } - - onKeyDown = (e) => { - const { suggestions, disabled } = this.props; - const { selectedSuggestion, suggestionsHidden } = this.state; - - if (disabled) { - e.preventDefault(); - return; - } - - switch(e.key) { - case 'Escape': - if (!suggestionsHidden) { - e.preventDefault(); - this.setState({ suggestionsHidden: true }); - } - - break; - case 'ArrowDown': - if (suggestions.size > 0 && !suggestionsHidden) { - e.preventDefault(); - this.setState({ selectedSuggestion: Math.min(selectedSuggestion + 1, suggestions.size - 1) }); - } - - break; - case 'ArrowUp': - if (suggestions.size > 0 && !suggestionsHidden) { - e.preventDefault(); - this.setState({ selectedSuggestion: Math.max(selectedSuggestion - 1, 0) }); - } - - break; - case 'Enter': - case 'Tab': - // Select suggestion - if (this.state.lastToken !== null && suggestions.size > 0 && !suggestionsHidden) { - e.preventDefault(); - e.stopPropagation(); - this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion)); - } - - break; - } - - if (e.defaultPrevented || !this.props.onKeyDown) { - return; - } - - this.props.onKeyDown(e); - } - - onKeyUp = e => { - if (e.key === 'Escape' && this.state.suggestionsHidden) { - document.querySelector('.ui').parentElement.focus(); - } - - if (this.props.onKeyUp) { - this.props.onKeyUp(e); - } - } - - onBlur = () => { - this.setState({ suggestionsHidden: true }); - } - - onSuggestionClick = (e) => { - const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index')); - e.preventDefault(); - this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion); - this.textarea.focus(); - } - - componentWillReceiveProps (nextProps) { - if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden) { - this.setState({ suggestionsHidden: false }); - } - } - - setTextarea = (c) => { - this.textarea = c; - } - - onPaste = (e) => { - if (e.clipboardData && e.clipboardData.files.length === 1) { - this.props.onPaste(e.clipboardData.files); - e.preventDefault(); - } - } - - renderSuggestion = (suggestion, i) => { - const { selectedSuggestion } = this.state; - let inner, key; - - if (typeof suggestion === 'object') { - inner = ; - key = suggestion.id; - } else { - inner = ; - key = suggestion; - } - - return ( -
- {inner} -
- ); - } - - render () { - const { value, suggestions, disabled, placeholder, autoFocus } = this.props; - const { suggestionsHidden } = this.state; - const style = { direction: 'ltr' }; - - if (isRtl(value)) { - style.direction = 'rtl'; - } - - return ( -
-