@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make the client authoritative for "Cancel" actions

Summary:
Ref T13559. When the user clicks the "Cancel" button, we sometimes take it to mean "delete" (when the comment is empty).

Both the client and server make a decision about this, and they may not agree, which causes the client to fall out of sync.

Make the client responsible for deciding whether it wants to interpret a click on the "Cancel" button as a "revert" or a "delete".

Test Plan: Cancelled empty and nonempty comments, etc. See followup changes.

Maniphest Tasks: T13559

Differential Revision: https://secure.phabricator.com/D21649

+53 -49
+7 -7
resources/celerity/map.php
··· 13 13 'core.pkg.js' => 'ab3502fe', 14 14 'dark-console.pkg.js' => '187792c2', 15 15 'differential.pkg.css' => 'ffb69e3d', 16 - 'differential.pkg.js' => '7747755e', 16 + 'differential.pkg.js' => 'fdec5f60', 17 17 'diffusion.pkg.css' => '42c75c37', 18 18 'diffusion.pkg.js' => '78c9885d', 19 19 'maniphest.pkg.css' => '35995d6d', ··· 385 385 'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '0116d3e8', 386 386 'rsrc/js/application/diff/DiffChangeset.js' => 'd7d3ba75', 387 387 'rsrc/js/application/diff/DiffChangesetList.js' => 'cc2c5de5', 388 - 'rsrc/js/application/diff/DiffInline.js' => '34ccdeda', 388 + 'rsrc/js/application/diff/DiffInline.js' => '2a6fac17', 389 389 'rsrc/js/application/diff/DiffInlineContentState.js' => '68e6339d', 390 390 'rsrc/js/application/diff/DiffPathView.js' => '8207abf9', 391 391 'rsrc/js/application/diff/DiffTreeView.js' => '5d83623b', ··· 788 788 'phabricator-dashboard-css' => '5a205b9d', 789 789 'phabricator-diff-changeset' => 'd7d3ba75', 790 790 'phabricator-diff-changeset-list' => 'cc2c5de5', 791 - 'phabricator-diff-inline' => '34ccdeda', 791 + 'phabricator-diff-inline' => '2a6fac17', 792 792 'phabricator-diff-inline-content-state' => '68e6339d', 793 793 'phabricator-diff-path-view' => '8207abf9', 794 794 'phabricator-diff-tree-view' => '5d83623b', ··· 1166 1166 'javelin-stratcom', 1167 1167 'javelin-behavior', 1168 1168 ), 1169 + '2a6fac17' => array( 1170 + 'javelin-dom', 1171 + 'phabricator-diff-inline-content-state', 1172 + ), 1169 1173 '2a8b62d9' => array( 1170 1174 'multirow-row-manager', 1171 1175 'javelin-install', ··· 1219 1223 'javelin-dom', 1220 1224 'javelin-stratcom', 1221 1225 'javelin-workflow', 1222 - ), 1223 - '34ccdeda' => array( 1224 - 'javelin-dom', 1225 - 'phabricator-diff-inline-content-state', 1226 1226 ), 1227 1227 '34e2a838' => array( 1228 1228 'aphront-typeahead-control-css',
-4
src/infrastructure/diff/PhabricatorInlineCommentController.php
··· 248 248 // to set the stored state back to "A". 249 249 $this->updateCommentContentState($inline); 250 250 251 - if ($inline->isVoidComment($viewer)) { 252 - $inline->setIsDeleted(1); 253 - } 254 - 255 251 $this->saveComment($inline); 256 252 257 253 return $this->buildEmptyResponse();
+46 -38
webroot/rsrc/js/application/diff/DiffInline.js
··· 829 829 if (this._shouldDeleteOnSave()) { 830 830 this._setPreventUndo(true); 831 831 this._applyDelete(); 832 - } else { 833 - this._applySave(); 832 + return; 834 833 } 834 + 835 + this._applySave(); 835 836 }, 836 837 837 838 _shouldDeleteOnSave: function() { ··· 843 844 return !state.getText().length; 844 845 }, 845 846 847 + _shouldDeleteOnCancel: function() { 848 + var state = this._getActiveContentState(); 849 + 850 + // TODO: This is greatly simplified, too. 851 + 852 + return !state.getText().length; 853 + }, 854 + 855 + _shouldUndoOnCancel: function() { 856 + var state = this._getActiveContentState().getWireFormat(); 857 + 858 + // TODO: This is also simplified. 859 + 860 + var is_empty = this._isVoidContentState(state); 861 + var is_same = this._isSameContentState(state, this._originalState); 862 + 863 + if (!is_empty && !is_same) { 864 + return true; 865 + } 866 + 867 + return false; 868 + }, 869 + 846 870 _applySave: function() { 847 871 var handler = JX.bind(this, this._onsaveresponse); 848 872 ··· 856 880 var handler = JX.bind(this, this._ondeleteresponse); 857 881 858 882 var data = this._newRequestData('delete'); 883 + 884 + this._applyCall(handler, data); 885 + }, 886 + 887 + _applyCancel: function(state) { 888 + var handler = JX.bind(this, this._onCancelResponse); 889 + 890 + var data = this._newRequestData('cancel', state); 859 891 860 892 this._applyCall(handler, data); 861 893 }, ··· 903 935 }, 904 936 905 937 cancel: function() { 906 - var state = this._getActiveContentState().getWireFormat(); 907 - 908 938 JX.DOM.remove(this._editRow); 909 939 this._editRow = null; 910 940 911 - var is_empty = this._isVoidContentState(state); 912 - var is_same = this._isSameContentState(state, this._originalState); 913 - if (!is_empty && !is_same) { 914 - this._drawUneditRows(state); 941 + if (this._shouldDeleteOnCancel()) { 942 + this._setPreventUndo(true); 943 + this._applyDelete(); 944 + return; 915 945 } 916 946 917 - // If this was an empty box and we typed some text and then hit cancel, 918 - // don't show the empty concrete inline. 919 - if (this._isVoidContentState(this._originalState)) { 920 - this.setInvisible(true); 921 - } else { 922 - this.setInvisible(false); 947 + if (this._shouldUndoOnCancel()) { 948 + var state = this._getActiveContentState().getWireFormat(); 949 + this._drawUneditRows(state); 923 950 } 924 951 925 952 // If you "undo" to restore text ("AB") and then "Cancel", we put you 926 953 // back in the original text state ("A"). We also send the original 927 954 // text ("A") to the server as the current persistent state. 928 955 929 - var uri = this._getInlineURI(); 930 - var data = this._newRequestData('cancel', this._originalState); 931 - var handler = JX.bind(this, this._onCancelResponse); 956 + this.setEditing(false); 957 + this.setInvisible(false); 932 958 933 - this.setLoading(true); 934 - 935 - new JX.Request(uri, handler) 936 - .setData(data) 937 - .send(); 959 + this._applyCancel(this._originalState); 938 960 939 961 this._didUpdate(true); 940 962 }, 941 963 942 964 _onCancelResponse: function(response) { 943 - this.setEditing(false); 944 - this.setLoading(false); 945 - 946 - // If the comment was empty when we started editing it (there's no 947 - // original text) and empty when we finished editing it (there's no 948 - // undo row), just delete the comment. 949 - if (this._isVoidContentState(this._originalState) && !this.isUndo()) { 950 - this.setDeleted(true); 951 - 952 - JX.DOM.remove(this._row); 953 - this._row = null; 954 - 955 - this._didUpdate(); 956 - } 965 + // Nothing to do. 957 966 }, 958 967 959 968 _getSuggestionNode: function(row) { ··· 970 979 this._editRow = null; 971 980 } 972 981 973 - this.setLoading(false); 982 + this.setEditing(false); 974 983 this.setInvisible(false); 975 - this.setEditing(false); 976 984 977 985 var new_row = this._drawContentRows(JX.$H(response.view).getNode()); 978 986 JX.DOM.remove(this._row);