Skip to content

Commit

Permalink
add edit conflict detection (#332)
Browse files Browse the repository at this point in the history
* add edit conflict detection for handleComment

- Only checks handleComment for now. Once we figure out a good approach in code review, will expand this to handleAccept, handleDecline, and handleReject in a future patch.
- Only checks when the submit button is clicked, to avoid spamming the Wikimedia API.
- When an edit conflict is detected, hides the submit button and displays a red warning message with a link to the draft's edit history.
- Makes it difficult to continue if an edit conflict is detected, forcing the user to reload the page. This is because continuing anyway would likely overwrite the previous edit.

Related #153

* fix promise bug. finish feature

* remove debugging code
  • Loading branch information
NovemLinguae authored Apr 23, 2024
1 parent cdb6379 commit 3339f99
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 8 deletions.
5 changes: 5 additions & 0 deletions src/less/submissions.less
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
vertical-align: top;
}

#afchEditConflict {
display: none;
color: red;
}

#afchSubmitForm {
text-align: center;
width: 30%;
Expand Down
50 changes: 47 additions & 3 deletions src/modules/submissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1367,10 +1367,18 @@
// Also provide extra data
$.extend( data, extraData );

prepareForProcessing();
checkForEditConflict().then( function ( editConflict ) {
if ( editConflict ) {
showEditConflictMessage();
return;
}

// Now finally call the applicable handler
fn( data );
// Hide the HTML form. Show #afchStatus messages
prepareForProcessing();

// Now finally call the applicable handler
fn( data );
} );
} );
} );
}
Expand Down Expand Up @@ -2608,6 +2616,42 @@
} );
}

function checkForEditConflict() {
// Get all revisions since the page was loaded, starting with the revision of the loaded page
var request = {
action: 'query',
format: 'json',
prop: 'revisions',
titles: [ mw.config.get( 'wgPageName' ) ],
formatversion: 2,
rvstartid: mw.config.get( 'wgRevisionId' ),
rvdir: 'newer'
};
var promise = AFCH.api.postWithEditToken( request )
.then( function ( data ) {
var revisions = data.query.pages[ 0 ].revisions;
// 1 revision = no edit conflict, 2+ revisions = edit conflict.
if ( revisions && revisions.length > 1 ) {
return true;
}
return false;
} );
return promise;
}

function showEditConflictMessage() {
$( '#afchSubmitForm' ).hide();

// Putting this here instead of in tpl-submissions.html to reduce code duplication
var editConflictHtml = 'Edit conflict! Your changes were not saved. Please check the <a id="afchHistoryLink" href="">page history</a>. To avoid overwriting the other person\'s edits, please refresh this page and start again.';
$( '#afchEditConflict' ).html( editConflictHtml );

var historyLink = new mw.Uri( mw.util.getUrl( mw.config.get( 'wgPageName' ), { action: 'history' } ) );
$( '#afchHistoryLink' ).prop( 'href', historyLink );

$( '#afchEditConflict' ).show();
}

function handleComment( data ) {
var text = data.afchText;

Expand Down
19 changes: 14 additions & 5 deletions src/templates/tpl-submissions.html
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@
<input type="checkbox" id="notifyUser" class="afch-input" checked/>
</div>

<div id="afchEditConflict"></div>

<div id="afchSubmitForm" data-running="Accepting submission..." class="gradient-button accept">Accept &amp; publish</div>

</div>
Expand Down Expand Up @@ -304,6 +306,8 @@
</div>
</div>

<div id="afchEditConflict"></div>

<div id="afchSubmitForm" data-running="Declining submission..." class="gradient-button button-centered decline hidden">Decline submission</div>

</div>
Expand All @@ -321,10 +325,12 @@

<div id="commentPreview"></div>

<div class="afch-option">
<input type="checkbox" id="notifyUser" class="afch-input" {{#notifyByDefault}}checked{{/notifyByDefault}} />
<label for="notifyUser" class="afch-label">Notify submitter</label>
</div>
<div class="afch-option">
<input type="checkbox" id="notifyUser" class="afch-input" {{#notifyByDefault}}checked{{/notifyByDefault}} />
<label for="notifyUser" class="afch-label">Notify submitter</label>
</div>

<div id="afchEditConflict"></div>

<div id="afchSubmitForm" data-running="Commenting on submission..." class="gradient-button button-centered comment">Post comment</div>

Expand All @@ -351,6 +357,8 @@
<div id="submitterNameStatus" class="error"></div>
</div>

<div id="afchEditConflict"></div>

<div id="afchSubmitForm" data-running="Submitting..." class="gradient-button button-centered submit">Submit</div>

</div>
Expand All @@ -365,10 +373,11 @@
placeholder="Enter your rationale for postponing deletion, which will be added to the submission as a new comment."
cols="100" rows="5"></textarea>

<div id="afchEditConflict"></div>

<div id="afchSubmitForm" data-running="Postponing..." class="gradient-button button-centered postpone-g13">
Postpone deletion
</div>

</div>
</div>
<!-- /postpone-g13 -->
Expand Down

0 comments on commit 3339f99

Please sign in to comment.