Block Other Users From Deleting Comments

Are you missing a feature? Request its implementation here.
dreifsnider
Posts: 66
Joined: Thu Aug 30, 2018 10:06 pm

Block Other Users From Deleting Comments

Post by dreifsnider »

Hi,

I recently installed the Block Change Tracking Deletion sample plugin (https://github.com/oxygenxml/web-author ... uggestions).

But I noticed that it only blocks the deletion of changes and not comments. Is there a way to also block deleting other user's comments?

For what it's worth, it looks like the plugin uses the getChangeHighlights method, but I wasn't able to find a corresponding get comments method in the ReviewController interface (https://www.oxygenxml.com/InstData/Edit ... oller.html).
cristi_talau
Posts: 481
Joined: Thu Sep 04, 2014 4:22 pm

Re: Block Other Users From Deleting Comments

Post by cristi_talau »

Hello,
You are right, to find the comments you should follow a different route:

Code: Select all

AuthorDocumentModel.getAuthorAccess().getReviewController().getCommentHighlights()
Best,
Cristian
dreifsnider
Posts: 66
Joined: Thu Aug 30, 2018 10:06 pm

Re: Block Other Users From Deleting Comments

Post by dreifsnider »

Thank you Cristian! I'll try getCommentHighlights() and will report back.

Daniel
dreifsnider
Posts: 66
Joined: Thu Aug 30, 2018 10:06 pm

Re: Block Other Users From Deleting Comments

Post by dreifsnider »

Hi Cristian,

I'm trying to get

Code: Select all

AuthorDocumentModel.getAuthorAccess().getReviewController().getCommentHighlights()
to work, but for some reason it doesn't seem to be working as I would expect, as I still have the ability to delete another user's comments in a review task that I am not the owner of:
content-fusion-able-to-delete-comment.png
content-fusion-able-to-delete-comment.png (109.4 KiB) Viewed 1222 times
I created a new plugin based off https://github.com/oxygenxml/web-author ... uggestions and added a new function named hasCommentsMadeByOthers (line31):

Code: Select all

function applicationStarted(pluginWorkspaceAccess) {
    pluginWorkspaceAccess.addEditingSessionLifecycleListener(
        new JavaAdapter(Packages.ro.sync.ecss.extensions.api.webapp.access.WebappEditingSessionLifecycleListener, {
            editingSessionStarted: function (docId, authorDocumentModel) {
                var blockSuggestionDeletion = new JavaAdapter(Packages.ro.sync.ecss.extensions.api.AuthorDocumentFilter, {
                    "delete": function(bypass, start, end, backspace) {
                        if (shouldBlockDeletion(start, end)) {
                            warnUser();
                            return false;
                        } else {
                            return bypass['delete'](start, end, backspace);
                        }
                    },
                    deleteNode: function(bypass, node) {
                        if (shouldBlockDeletion(node.getStartOffset(), node.getEndOffset())) {
                            warnUser();
                            return false;
                        } else {
                            return bypass.deleteNode(node);
                        }
                    },
                });

                authorDocumentModel.getAuthorAccess().getDocumentController().setDocumentFilter(blockSuggestionDeletion);

                function shouldBlockDeletion(start, end) {
                    var reviewController = authorDocumentModel.getReviewController();
                    return reviewController.isTrackingChanges() && hasCommentsMadeByOthers(start, end);
                }

                function hasCommentsMadeByOthers(start, end) {
                    var reviewController = authorDocumentModel.getAuthorAccess().getReviewController();
                    var comments = reviewController.getCommentHighlights(start, end) || [];
                    var authors = getCommentAuthors(comments);

                    var currentAuthor = reviewController.getReviewerAuthorName();
                    return authors.length > 1 || authors.length === 1 && authors[0] !== currentAuthor;
                }

                function getCommentAuthors(comments) {
                    var authors = [];
                    for (var i = 0; i < comments.length; i++) {
                        var commentAuthor = comments[i].getProperty("author");
                        if (authors.indexOf(commentAuthor) === -1) {
                            authors.push(commentAuthor);
                        }
                    }
                    return authors;
                }

                function warnUser() {
                    authorDocumentModel.getAuthorAccess().getWorkspaceAccess().showWarningMessage(
                        "Cannot delete another user's suggestions or comments. Use a comment to suggest your change.");
                }
            }
        }));
}

function applicationClosing(pluginWorkspaceAccess) {
    // Nothing to do.
}
Could you please provide some guidance as to what I'm doing wrong or need to do instead to block the deletion of comments?

Thank you!

Daniel
mihaela
Posts: 475
Joined: Wed May 20, 2009 2:40 pm

Re: Block Other Users From Deleting Comments

Post by mihaela »

Hello,

I tried your code in a plugin and it works, I cannot delete the content included in a comment added by another user. However, a small observation: it works only when I have the track changes mode on. Is this mode enabled when you test? See the shouldBlockDeletion method (you check for reviewController.isTrackingChanges()):

Code: Select all

 function shouldBlockDeletion(start, end) {
    var reviewController = authorDocumentModel.getReviewController();
    return reviewController.isTrackingChanges() && hasCommentsMadeByOthers(start, end);
}
Best Regards,
Mihaela
Mihaela Calotescu
http://www.oxygenxml.com
dreifsnider
Posts: 66
Joined: Thu Aug 30, 2018 10:06 pm

Re: Block Other Users From Deleting Comments

Post by dreifsnider »

Hi Mihaela,

Thank you for your reply!

I believe I now better understanding the functionality of the https://github.com/oxygenxml/web-author ... uggestions plugin, and I can confirm that my new plugin based on this works as designed: it blocks the user from deleting the actual content in the topic when the content has been surrounded by a persistent highlight (in my plugin's case it targets comments) that was created by another user.

I was also expecting the plugin to block the user from deleting the marker in the Review tab as well, as the user could still easily delete the change/comment made by the other user and then supply their own change/comment.

I was able to use the removeMarker() method to successfully block the user from also deleting the comment itself:

Code: Select all

removeMarker: function(bypass, marker) {
  if (shouldBlockDeletion(marker.getStartOffset(), marker.getEndOffset())) {
        warnUser();
        return false;
  } else {
        return bypass.removeMarker(marker);
  }
}
Thank you very much for your help with this!

I did notice a minor issue with using this method though: I'm unable to delete my own replies to another user's comment. However, I can still delete my own comments. I'm not sure why exactly this is happening, but I suspect it's because my reply is nested under the other user's comment, and therefore, I'm unable to delete anything under the other user's comment including my own?

I also recorded a screen capture of this experience to help explain this issue: https://sie.box.com/s/hcnf2c900fgi503ogge26u4x49y6yo77

Thanks again!

Daniel
mihaela
Posts: 475
Joined: Wed May 20, 2009 2:40 pm

Re: Block Other Users From Deleting Comments

Post by mihaela »

Hello,

The problem you encounter when you try to delete your reply is that you do not check the marker that you receive as a parameter on the removeMarker method (I think you use the same method as when deleting the content). You should check if the marker has the type [1] ro.sync.ecss.extensions.api.highlights.AuthorPersistentHighlight.PersistentHighlightType.COMMENT [2] and that its author is not the current author.

[1] https://www.oxygenxml.com/InstData/Edit ... #getType--
[2] https://www.oxygenxml.com/InstData/Edit ... ml#COMMENT

Best Regards,
Mihaela
Mihaela Calotescu
http://www.oxygenxml.com
dreifsnider
Posts: 66
Joined: Thu Aug 30, 2018 10:06 pm

Re: Block Other Users From Deleting Comments

Post by dreifsnider »

Hi Mihaela,

Thank you again for your reply and your help on this.

Because of my inexperience with Java, I'm still struggling to get the removeMarker method to check the type of the marker.

For what it's worth, I did create two separate methods to check whether or not the comment or change should be deleted (shouldBlockCommentDeletion and shouldBlockChangeDeletion). Within these two methods I believe I'm checking the type of the persistent highlight. But it's still not working as I would expect, i.e., that the current user is blocked from deleting another user's comments and changes, but that they can still delete their own comments and changes.

Would you be able to take a look at the following code I'm using and tell me what I need to do to get this working?

Code: Select all

function applicationStarted(pluginWorkspaceAccess) {
    pluginWorkspaceAccess.addEditingSessionLifecycleListener(
        new JavaAdapter(Packages.ro.sync.ecss.extensions.api.webapp.access.WebappEditingSessionLifecycleListener, {
            editingSessionStarted: function (docId, authorDocumentModel) {
                var blockSuggestionDeletion = new JavaAdapter(Packages.ro.sync.ecss.extensions.api.AuthorDocumentFilter, {
                    "delete": function(bypass, start, end, backspace) {
                        if (shouldBlockCommentDeletion(start, end)) {
                            warnUser();
                            return false;
                        } if (shouldBlockChangeDeletion(start, end)) {
                            warnUser();
                            return false;
                        }
                        else {
                            return bypass['delete'](start, end, backspace);
                        }
                    },
                    deleteNode: function(bypass, node) {
                        if (shouldBlockCommentDeletion(node.getStartOffset(), node.getEndOffset())) {
                            warnUser();
                            return false;
                        }
                        if (shouldBlockChangeDeletion(node.getStartOffset(), node.getEndOffset())) {
                            warnUser();
                            return false;
                        } else {
                            return bypass.deleteNode(node);
                        }
                    },
                    removeMarker: function(bypass, marker) {
                      if (shouldBlockCommentDeletion(marker.getStartOffset(), marker.getEndOffset())) {
                            warnUser();
                            return false;
                      } if (shouldBlockChangeDeletion(marker.getStartOffset(), marker.getEndOffset())) {
                            warnUser();
                            return false;
                      } else {
                            return bypass.removeMarker(marker);
                      }
                    },
                });

                authorDocumentModel.getAuthorAccess().getDocumentController().setDocumentFilter(blockSuggestionDeletion);

                function shouldBlockCommentDeletion(start, end) {
                    var reviewController = authorDocumentModel.getAuthorAccess().getReviewController();
                    var type = new JavaAdapter(Packages.ro.sync.ecss.extensions.api.highlights.AuthorPersistentHighlight.getType());
                    return reviewController.isTrackingChanges() && hasCommentsMadeByOthers(start, end) && type === COMMENT;
                }

                function shouldBlockChangeDeletion(start, end) {
                    var reviewController = authorDocumentModel.getReviewController();
                    var type = new JavaAdapter(Packages.ro.sync.ecss.extensions.api.highlights.AuthorPersistentHighlight.getType());
                    return reviewController.isTrackingChanges() && hasChangesMadeByOthers(start, end) && type !== COMMENT;
                }

                function hasCommentsMadeByOthers(start, end) {
                    var reviewController = authorDocumentModel.getAuthorAccess().getReviewController();
                    var comments = reviewController.getCommentHighlights(start, end) || [];
                    var commentAuthors = getCommentAuthors(comments);

                    var currentAuthor = reviewController.getReviewerAuthorName();
                    return commentAuthors.length > 1 || commentAuthors.length === 1 && commentAuthors[0] !== currentAuthor;
                }

                function hasChangesMadeByOthers(start, end) {
                    var reviewController = authorDocumentModel.getReviewController();
                    var changes = reviewController.getChangeHighlights(start, end) || [];
                    var changeAuthors = getChangeAuthors(changes);

                    var currentAuthor = reviewController.getReviewerAuthorName();
                    return changeAuthors.length > 1 || changeAuthors.length === 1 && changeAuthors[0] !== currentAuthor;
                }

                function getCommentAuthors(comments) {
                    var commentAuthors = [];
                    for (var i = 0; i < comments.length; i++) {
                        var commentAuthor = comments[i].getProperty("author");
                        if (commentAuthors.indexOf(commentAuthor) === -1) {
                            commentAuthors.push(commentAuthor);
                        }
                    }
                    return commentAuthors;
                }

                function getChangeAuthors(changes) {
                    var changeAuthors = [];
                    for (var i = 0; i < changes.length; i++) {
                        var changeAuthor = changes[i].getProperty("author");
                        if (changeAuthors.indexOf(changeAuthor) === -1) {
                            changeAuthors.push(changeAuthor);
                        }
                    }
                    return changeAuthors;
                }

                function warnUser() {
                    authorDocumentModel.getAuthorAccess().getWorkspaceAccess().showWarningMessage(
                        "Cannot delete another user's comment or change. Use a comment to suggest your change.");
                }
            }
        }));
}

function applicationClosing(pluginWorkspaceAccess) {
    // Nothing to do.
}
I have also uploaded this to my company's Box: https://sie.box.com/s/x57s4aa7z9fj13ei6o376yiyl0bylae3

Thank you very much!

Daniel
mihaela
Posts: 475
Joined: Wed May 20, 2009 2:40 pm

Re: Block Other Users From Deleting Comments

Post by mihaela »

Hello,

Indeed to implement this plugin you need to have some JAVA knowledge. We already have an issue registered in our internal issues tracking system for this feature - to block other users from deleting comments - so we plan to implement it at some point. How important is this feature for you? It will be used by many users? Is ok for you to wait until will be implemented by us or do you need to make it available as soon as possible? If you want you can write the answer by email, at support@oxygenxml.com.

To be able to debug the plugin code, you can add some logs. For example, if you add the following line in the removeMarker method, you will see in the server logs [1] information about the marker object that you receive as a parameter:

Code: Select all

 java.lang.System.out.println(marker);
Regarding your question about the marker type, this can be checked only in the removeMarker method, where you have access to the marker object, like this:

Code: Select all

if (marker.getType() === Packages.ro.sync.ecss.extensions.api.highlights.AuthorPersistentHighlight.PersistentHighlightType.COMMENT) {
// your code here
}
[1] https://www.oxygenxml.com/doc/versions/ ... uthor-logs

Best Regards,
Mihaela
Mihaela Calotescu
http://www.oxygenxml.com
dreifsnider
Posts: 66
Joined: Thu Aug 30, 2018 10:06 pm

Re: Block Other Users From Deleting Comments

Post by dreifsnider »

Hi Mihaela,

Thank you very much for your reply! That's great news that you have this registered as an internal issue and that you plan on implementing it at some point. I will email support@oxygenxml.com in regards to the priority and timing for this feature.

Thank you for all your guidance and assistance on this, and for providing the below code snippet. I will work on improving my Java skills so hopefully I won't have to lean on you and everyone else at SyncroSoft as much for these types of requests. :D

Thanks again!

Daniel
Post Reply