about summary refs log tree commit diff
path: root/app/javascript
diff options
context:
space:
mode:
authorThibG <thib@sitedethib.com>2018-05-26 13:22:49 +0200
committerGitHub <noreply@github.com>2018-05-26 13:22:49 +0200
commit22bc07998c7559a02b6a6ad0b3a23fc00ce2cf5b (patch)
tree6ee622a43c4d8f40fa6bdf615e1d0263921010ab /app/javascript
parenta5c25242af65b20c3157321b566f739a27f21e21 (diff)
parent18d9a7fd718f8c56f2680057fbed5b550e748b0d (diff)
Merge pull request #508 from ThibG/glitch-soc/fixes/remove-leftover-from-attachment-url-insertion
Fix caret position after inserting suggestions
Diffstat (limited to 'app/javascript')
-rw-r--r--app/javascript/flavours/glitch/features/composer/index.js27
-rw-r--r--app/javascript/flavours/glitch/reducers/compose.js8
2 files changed, 13 insertions, 22 deletions
diff --git a/app/javascript/flavours/glitch/features/composer/index.js b/app/javascript/flavours/glitch/features/composer/index.js
index de85340a3..21b03be39 100644
--- a/app/javascript/flavours/glitch/features/composer/index.js
+++ b/app/javascript/flavours/glitch/features/composer/index.js
@@ -56,6 +56,7 @@ function mapStateToProps (state) {
     advancedOptions: state.getIn(['compose', 'advanced_options']),
     amUnlocked: !state.getIn(['accounts', me, 'locked']),
     focusDate: state.getIn(['compose', 'focusDate']),
+    caretPosition: state.getIn(['compose', 'caretPosition']),
     isSubmitting: state.getIn(['compose', 'is_submitting']),
     isUploading: state.getIn(['compose', 'is_uploading']),
     layout: state.getIn(['local_settings', 'layout']),
@@ -117,7 +118,6 @@ const handlers = {
   handleEmoji (data) {
     const { textarea: { selectionStart } } = this;
     const { onInsertEmoji } = this.props;
-    this.caretPos = selectionStart + data.native.length + 1;
     if (onInsertEmoji) {
       onInsertEmoji(selectionStart, data);
     }
@@ -139,7 +139,6 @@ const handlers = {
   //  Selects a suggestion from the autofill.
   handleSelect (tokenStart, token, value) {
     const { onSelectSuggestion } = this.props;
-    this.caretPos = null;
     if (onSelectSuggestion) {
       onSelectSuggestion(tokenStart, token, value);
     }
@@ -191,20 +190,9 @@ class Composer extends React.Component {
     assignHandlers(this, handlers);
 
     //  Instance variables.
-    this.caretPos = null;
     this.textarea = null;
   }
 
-  //  If this is the update where we've finished uploading,
-  //  save the last caret position so we can restore it below!
-  componentWillReceiveProps (nextProps) {
-    const { textarea } = this;
-    const { isUploading } = this.props;
-    if (textarea && isUploading && !nextProps.isUploading) {
-      this.caretPos = textarea.selectionStart;
-    }
-  }
-
   //  Tells our state the composer has been mounted.
   componentDidMount () {
     const { onMount } = this.props;
@@ -228,17 +216,13 @@ class Composer extends React.Component {
   //      - Replying to more than one user, selects any usernames past
   //        the first; this provides a convenient shortcut to drop
   //        everyone else from the conversation.
-  // - If we've just finished uploading an image, and have a saved
-  //   caret position, restores the cursor to that position after the
-  //   text changes.
   componentDidUpdate (prevProps) {
     const {
-      caretPos,
       textarea,
     } = this;
     const {
       focusDate,
-      isUploading,
+      caretPosition,
       isSubmitting,
       preselectDate,
       text,
@@ -246,14 +230,14 @@ class Composer extends React.Component {
     let selectionEnd, selectionStart;
 
     //  Caret/selection handling.
-    if (focusDate !== prevProps.focusDate || (prevProps.isUploading && !isUploading && !isNaN(caretPos) && caretPos !== null)) {
+    if (focusDate !== prevProps.focusDate) {
       switch (true) {
       case preselectDate !== prevProps.preselectDate:
         selectionStart = text.search(/\s/) + 1;
         selectionEnd = text.length;
         break;
-      case !isNaN(caretPos) && caretPos !== null:
-        selectionStart = selectionEnd = caretPos;
+      case !isNaN(caretPosition) && caretPosition !== null:
+        selectionStart = selectionEnd = caretPosition;
         break;
       default:
         selectionStart = selectionEnd = text.length;
@@ -410,6 +394,7 @@ Composer.propTypes = {
   advancedOptions: ImmutablePropTypes.map,
   amUnlocked: PropTypes.bool,
   focusDate: PropTypes.instanceOf(Date),
+  caretPosition: PropTypes.number,
   isSubmitting: PropTypes.bool,
   isUploading: PropTypes.bool,
   layout: PropTypes.string,
diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js
index f79fa63d2..24a8af86f 100644
--- a/app/javascript/flavours/glitch/reducers/compose.js
+++ b/app/javascript/flavours/glitch/reducers/compose.js
@@ -56,6 +56,7 @@ const initialState = ImmutableMap({
   privacy: null,
   text: '',
   focusDate: null,
+  caretPosition: null,
   preselectDate: null,
   in_reply_to: null,
   is_submitting: false,
@@ -148,6 +149,7 @@ function continueThread (state, status) {
     map.update('media_attachments', list => list.clear());
     map.set('idempotencyKey', uuid());
     map.set('focusDate', new Date());
+    map.set('caretPosition', null);
     map.set('preselectDate', new Date());
   });
 }
@@ -159,7 +161,6 @@ function appendMedia(state, media) {
     map.update('media_attachments', list => list.push(media));
     map.set('is_uploading', false);
     map.set('resetFileKey', Math.floor((Math.random() * 0x10000)));
-    map.set('focusDate', new Date());
     map.set('idempotencyKey', uuid());
 
     if (prevSize === 0 && (state.get('default_sensitive') || state.get('spoiler'))) {
@@ -187,6 +188,7 @@ const insertSuggestion = (state, position, token, completion) => {
     map.set('suggestion_token', null);
     map.update('suggestions', ImmutableList(), list => list.clear());
     map.set('focusDate', new Date());
+    map.set('caretPosition', position + completion.length + 1);
     map.set('idempotencyKey', uuid());
   });
 };
@@ -197,6 +199,7 @@ const insertEmoji = (state, position, emojiData) => {
   return state.withMutations(map => {
     map.update('text', oldText => `${oldText.slice(0, position)}${emoji}\u200B${oldText.slice(position)}`);
     map.set('focusDate', new Date());
+    map.set('caretPosition', position + emoji.length + 1);
     map.set('idempotencyKey', uuid());
   });
 };
@@ -278,6 +281,7 @@ export default function compose(state = initialState, action) {
         map => map.merge(new ImmutableMap({ do_not_federate: /👁\ufe0f?\u200b?(?:<\/p>)?$/.test(action.status.get('content')) }))
       );
       map.set('focusDate', new Date());
+      map.set('caretPosition', null);
       map.set('preselectDate', new Date());
       map.set('idempotencyKey', uuid());
 
@@ -325,6 +329,7 @@ export default function compose(state = initialState, action) {
     return state.withMutations(map => {
       map.update('text', text => [text.trim(), `@${action.account.get('acct')} `].filter((str) => str.length !== 0).join(' '));
       map.set('focusDate', new Date());
+      map.set('caretPosition', null);
       map.set('idempotencyKey', uuid());
     });
   case COMPOSE_DIRECT:
@@ -332,6 +337,7 @@ export default function compose(state = initialState, action) {
       map.update('text', text => [text.trim(), `@${action.account.get('acct')} `].filter((str) => str.length !== 0).join(' '));
       map.set('privacy', 'direct');
       map.set('focusDate', new Date());
+      map.set('caretPosition', null);
       map.set('idempotencyKey', uuid());
     });
   case COMPOSE_SUGGESTIONS_CLEAR: