Package org.damour.base.client.ui.comment

Source Code of org.damour.base.client.ui.comment.CommentWidget

package org.damour.base.client.ui.comment;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.damour.base.client.images.BaseImageBundle;
import org.damour.base.client.objects.Comment;
import org.damour.base.client.objects.Page;
import org.damour.base.client.objects.PageInfo;
import org.damour.base.client.objects.PermissibleObject;
import org.damour.base.client.objects.PermissibleObjectTreeNode;
import org.damour.base.client.service.BaseServiceCache;
import org.damour.base.client.ui.authentication.AuthenticationHandler;
import org.damour.base.client.ui.buttons.Button;
import org.damour.base.client.ui.buttons.IconButton;
import org.damour.base.client.ui.dialogs.IDialogCallback;
import org.damour.base.client.ui.dialogs.IDialogValidatorCallback;
import org.damour.base.client.ui.dialogs.MessageDialogBox;
import org.damour.base.client.ui.dialogs.PromptDialogBox;
import org.damour.base.client.utils.CursorUtils;
import org.damour.base.client.utils.StringUtils;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class CommentWidget extends VerticalPanel {

  private PermissibleObject permissibleObject;
  private List<PermissibleObject> comments;
  private boolean sortDescending = true;
  private boolean flatten = false;
  private ListBox maxCommentDepthListBox = new ListBox(false);

  private Comment workingOnComment;

  private ICommentLayoutComplete layoutCallback;
  private int pageNumber = 0;
  private int pageSize = 10;
  private long numComments = 0;
  private long lastPageNumber = 0;
  private boolean paginate = true;

  HashMap<Integer, Page<PermissibleObject>> pageCache = new HashMap<Integer, Page<PermissibleObject>>();

  private AsyncCallback<Boolean> deleteCommentCallback = new AsyncCallback<Boolean>() {

    public void onSuccess(Boolean result) {
      BaseServiceCache.getService().getPageInfo(permissibleObject, Comment.class.getName(), pageSize, new AsyncCallback<PageInfo>() {
        public void onFailure(Throwable caught) {
        };

        public void onSuccess(PageInfo pageInfo) {
          numComments = pageInfo.getTotalRowCount();
          lastPageNumber = pageInfo.getLastPageNumber();
          while (pageNumber > lastPageNumber) {
            pageNumber--;
          }
          pageCache.clear();
          fetchPage();
        };
      });
    }

    public void onFailure(Throwable caught) {
      MessageDialogBox dialog = new MessageDialogBox("Error", caught.getMessage(), false, true, true);
      dialog.center();
    }
  };
  private AsyncCallback<Boolean> approveCallback = new AsyncCallback<Boolean>() {

    public void onSuccess(Boolean result) {
      workingOnComment.setApproved(true);
      loadCommentWidget(true);
    }

    public void onFailure(Throwable caught) {
      MessageDialogBox dialog = new MessageDialogBox("Error", caught.getMessage(), false, true, true);
      dialog.center();
      workingOnComment.setApproved(false);
      loadCommentWidget(true);
    }
  };
  private AsyncCallback<Boolean> submitCommentCallback = new AsyncCallback<Boolean>() {

    public void onSuccess(Boolean result) {
      BaseServiceCache.getService().getPageInfo(permissibleObject, Comment.class.getName(), pageSize, new AsyncCallback<PageInfo>() {
        public void onFailure(Throwable caught) {
        };

        public void onSuccess(PageInfo pageInfo) {
          numComments = pageInfo.getTotalRowCount();
          lastPageNumber = pageInfo.getLastPageNumber();
          while (pageNumber > lastPageNumber) {
            pageNumber--;
          }
          pageCache.clear();
          fetchPage();
        };
      });
    }

    public void onFailure(Throwable caught) {
      MessageDialogBox dialog = new MessageDialogBox("Error", caught.getMessage(), false, true, true);
      dialog.center();
    }
  };
  private AsyncCallback<Page<PermissibleObject>> pageCallback = new AsyncCallback<Page<PermissibleObject>>() {

    public void onSuccess(Page<PermissibleObject> page) {
      pageCache.put(page.getPageNumber(), page);
      comments = page.getResults();
      if (page.getResults().size() == 0) {
        pageNumber = 0;
        lastPageNumber = 0;
      }
      loadCommentWidget(true);
      prefetchPages();
    }

    public void onFailure(Throwable caught) {
      MessageDialogBox dialog = new MessageDialogBox("Error", caught.getMessage(), false, true, true);
      dialog.center();
    }
  };

  private AsyncCallback<List<PermissibleObject>> allCommentsCallback = new AsyncCallback<List<PermissibleObject>>() {
    public void onSuccess(List<PermissibleObject> comments) {
      CursorUtils.setDefaultCursor(CommentWidget.this);
      CommentWidget.this.comments = comments;
      numComments = comments.size();
      loadCommentWidget(true);
    }

    public void onFailure(Throwable caught) {
      CursorUtils.setDefaultCursor(CommentWidget.this);
      MessageDialogBox dialog = new MessageDialogBox("Error", caught.getMessage(), false, true, true);
      dialog.center();
    }
  };

  private AsyncCallback<Page<PermissibleObject>> preFetchPageCallback = new AsyncCallback<Page<PermissibleObject>>() {

    public void onSuccess(Page<PermissibleObject> page) {
      pageCache.put(page.getPageNumber(), page);
    }

    public void onFailure(Throwable caught) {
      MessageDialogBox dialog = new MessageDialogBox("Error", caught.getMessage(), false, true, true);
      dialog.center();
    }
  };

  public CommentWidget(final PermissibleObject permissibleObject, final List<PermissibleObject> comments, ICommentLayoutComplete layoutCallback,
      boolean paginate, int pageSize) {
    this.permissibleObject = permissibleObject;
    this.comments = comments;
    this.paginate = paginate;
    this.pageSize = pageSize;
    this.layoutCallback = layoutCallback;

    maxCommentDepthListBox.addItem("None", "999999");
    maxCommentDepthListBox.addItem("1");
    maxCommentDepthListBox.addItem("2");
    maxCommentDepthListBox.addItem("3");
    maxCommentDepthListBox.addItem("4");
    maxCommentDepthListBox.addItem("5");
    maxCommentDepthListBox.setSelectedIndex(0);
    maxCommentDepthListBox.addChangeHandler(new ChangeHandler() {

      public void onChange(ChangeEvent event) {
        loadCommentWidget(true);
      }
    });

    add(new Label("Loading..."));

    Timer t = new Timer() {
      public void run() {
        if (comments == null) {
          BaseServiceCache.getService().getPageInfo(permissibleObject, Comment.class.getName(), CommentWidget.this.pageSize, new AsyncCallback<PageInfo>() {
            public void onFailure(Throwable caught) {
            };

            public void onSuccess(PageInfo pageInfo) {
              numComments = pageInfo.getTotalRowCount();
              lastPageNumber = pageInfo.getLastPageNumber();
              fetchPage();
            };
          });
        } else {
          numComments = comments.size();
          if (CommentWidget.this.paginate) {
            // make pages
            lastPageNumber = new Double(Math.floor((double) (numComments - 1) / CommentWidget.this.pageSize)).longValue();

            int currPage = -1;
            List<PermissibleObject> sortedComments = sortComments(comments);
            for (int i = 0; i < numComments; i++) {
              if (i % CommentWidget.this.pageSize == 0) {
                currPage++;
              }
              if (pageCache.get(currPage) == null) {
                pageCache.put(currPage, new Page<PermissibleObject>());
              }
              Page<PermissibleObject> page = pageCache.get(currPage);
              page.setPageNumber(currPage);
              page.getResults().add(sortedComments.get(i));
            }
            if (pageCache.size() > 0) {
              CommentWidget.this.comments = pageCache.get(0).getResults();
            }
          }
          loadCommentWidget(true);
        }
      }
    };
    t.schedule(1);

  }

  private void loadCommentWidget(final boolean forceOpen) {
    clear();
    if (permissibleObject.isAllowComments()) {

      String fileName = permissibleObject.getName();
      final DisclosurePanel commentDisclosurePanel = new DisclosurePanel("View comments (" + numComments + ") for " + fileName);

      VerticalPanel commentsPanel = new VerticalPanel();
      commentsPanel.setSpacing(0);
      if (numComments > 0) {
        commentsPanel.setStyleName("commentsPanel");
      }
      commentsPanel.setWidth("100%");

      int renderedComments = 0;
      boolean userCanManage = AuthenticationHandler.getInstance().getUser() != null
          && (AuthenticationHandler.getInstance().getUser().isAdministrator() || AuthenticationHandler.getInstance().getUser()
              .equals(permissibleObject.getOwner()));
      List<PermissibleObject> sortedComments = new ArrayList<PermissibleObject>();
      if (comments != null) {
        sortedComments.addAll(comments);
      }
      if (!flatten) {
        sortedComments = sortComments(sortedComments);
      }

      for (PermissibleObject obj : sortedComments) {
        final Comment comment = (Comment) obj;
        int commentDepth = getCommentDepth(comment);

        int maxDepth = Integer.parseInt(maxCommentDepthListBox.getValue(maxCommentDepthListBox.getSelectedIndex()));
        if (commentDepth >= maxDepth) {
          continue;
        }

        boolean userIsAuthorOfComment = AuthenticationHandler.getInstance().getUser() != null && comment.getAuthor() != null
            && comment.getAuthor().equals(AuthenticationHandler.getInstance().getUser());

        if (userCanManage || userIsAuthorOfComment || comment.isApproved()) {

          FlexTable commentHeaderPanel = new FlexTable();
          commentHeaderPanel.setCellPadding(0);
          commentHeaderPanel.setCellSpacing(0);
          commentHeaderPanel.setStyleName("commentHeader");
          commentHeaderPanel.setWidth("100%");

          String authorLabelString = comment.getAuthor() == null ? comment.getEmail() : comment.getAuthor().getUsername();
          if (comment.getAuthor() != null && comment.getAuthor().getFirstname() != null && !"".equals(comment.getAuthor().getFirstname())) {
            authorLabelString += " (" + comment.getAuthor().getFirstname();
            if (comment.getAuthor() != null && comment.getAuthor().getLastname() != null && !"".equals(comment.getAuthor().getLastname())) {
              authorLabelString += " " + comment.getAuthor().getLastname() + ")";
            } else {
              authorLabelString += ")";
            }
          }

          Image replyCommentImage = new Image();
          replyCommentImage.setResource(BaseImageBundle.images.reply());
          replyCommentImage.setStyleName("commentActionButton");
          replyCommentImage.setTitle("Reply to this comment");
          replyCommentImage.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
              replyToComment(comment);
            }
          });
          int columnIndex = 0;
          commentHeaderPanel.setWidget(0, columnIndex, replyCommentImage);
          commentHeaderPanel.getFlexCellFormatter().setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_LEFT);
          columnIndex++;

          Label authorLabel = new Label(authorLabelString, false);
          commentHeaderPanel.setWidget(0, columnIndex, authorLabel);
          commentHeaderPanel.getFlexCellFormatter().setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_LEFT);
          columnIndex++;
          commentHeaderPanel.setWidget(0, columnIndex, new Label());
          commentHeaderPanel.getFlexCellFormatter().setWidth(0, columnIndex, "100%");
          commentHeaderPanel.getFlexCellFormatter().setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_RIGHT);
          columnIndex++;
          Label dateLabel = new Label(new Date(comment.getCommentDate()).toLocaleString(), false);
          commentHeaderPanel.setWidget(0, columnIndex, dateLabel);
          if (!userCanManage && !userIsAuthorOfComment) {
            DOM.setStyleAttribute(dateLabel.getElement(), "padding", "0 5px 0 0");
          }
          commentHeaderPanel.getFlexCellFormatter().setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_RIGHT);

          columnIndex++;
          if (userCanManage || userIsAuthorOfComment) {
            if (userCanManage && !comment.isApproved()) {
              final Image approveCommentImage = new Image();
              approveCommentImage.setResource(BaseImageBundle.images.approve());
              approveCommentImage.setStyleName("commentActionButton");
              approveCommentImage.setTitle("Approve comment");
              approveCommentImage.addClickHandler(new ClickHandler() {

                public void onClick(ClickEvent event) {
                  workingOnComment = comment;
                  approveComment(comment);
                }
              });
              commentHeaderPanel.setWidget(0, columnIndex, approveCommentImage);
              commentHeaderPanel.getFlexCellFormatter().setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_RIGHT);
              columnIndex++;
            } else {
              // put 16x16 spacer here for alignment
              final Image approveSpacerImage = new Image();
              approveSpacerImage.setResource(BaseImageBundle.images.empty16x16());
              approveSpacerImage.setStyleName("commentActionButton");
              commentHeaderPanel.setWidget(0, columnIndex, approveSpacerImage);
              commentHeaderPanel.getFlexCellFormatter().setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_RIGHT);
              columnIndex++;
            }
            Image deleteCommentImage = new Image();
            deleteCommentImage.setResource(BaseImageBundle.images.delete());
            deleteCommentImage.setStyleName("commentActionButton");
            deleteCommentImage.setTitle("Remove comment");
            deleteCommentImage.addClickHandler(new ClickHandler() {

              public void onClick(ClickEvent event) {
                IDialogCallback callback = new IDialogCallback() {

                  public void cancelPressed() {
                  }

                  public void okPressed() {
                    deleteComment(comment);
                  }
                };
                PromptDialogBox dialogBox = new PromptDialogBox("Question", "Yes", null, "No", false, true);
                dialogBox.setContent(new Label("Delete comment by " + (comment.getAuthor() == null ? comment.getEmail() : comment.getAuthor().getUsername())
                    + "?"));
                dialogBox.setCallback(callback);
                dialogBox.center();
              }
            });
            commentHeaderPanel.setWidget(0, columnIndex, deleteCommentImage);
            commentHeaderPanel.getFlexCellFormatter().setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_RIGHT);
            columnIndex++;
          }

          if (commentDepth > 0) {
            HorizontalPanel commentHeaderPanelWrapper = new HorizontalPanel();
            commentHeaderPanelWrapper.setWidth("100%");
            Label spacerLabel = new Label();
            commentHeaderPanelWrapper.add(spacerLabel);
            if (!flatten) {
              commentHeaderPanelWrapper.setCellWidth(spacerLabel, (commentDepth * 20) + "px");
            }
            commentHeaderPanelWrapper.add(commentHeaderPanel);
            commentsPanel.add(commentHeaderPanelWrapper);
          } else {
            commentsPanel.add(commentHeaderPanel);
          }

          // Label commentLabel = new Label(comment.getId() + " " + comment.getComment(), true);
          Label commentLabel = new Label(comment.getComment(), true);
          if (comment.isApproved()) {
            commentLabel.setStyleName("comment");
          } else if (userCanManage || userIsAuthorOfComment) {
            commentLabel.setStyleName("commentAwaitingApproval");
          }

          if (commentDepth > 0) {
            HorizontalPanel commentHeaderPanelWrapper = new HorizontalPanel();
            commentHeaderPanelWrapper.setWidth("100%");
            Label spacerLabel = new Label();
            commentHeaderPanelWrapper.add(spacerLabel);
            if (!flatten) {
              commentHeaderPanelWrapper.setCellWidth(spacerLabel, (commentDepth * 20) + "px");
            }
            commentHeaderPanelWrapper.add(commentLabel);
            commentsPanel.add(commentHeaderPanelWrapper);
          } else {
            commentsPanel.add(commentLabel);
          }
          renderedComments++;
        }
      }

      final FlexTable mainPanel = new FlexTable();
      mainPanel.setWidth("100%");
      int row = 0;
      if (paginate) {
        mainPanel.setWidget(row, 0, createButtonPanel(mainPanel, forceOpen));
        mainPanel.getCellFormatter().setHorizontalAlignment(row++, 0, HasHorizontalAlignment.ALIGN_LEFT);
      }
      mainPanel.setWidget(row, 0, commentsPanel);
      mainPanel.getCellFormatter().setWidth(row++, 0, "100%");

      commentDisclosurePanel.setContent(mainPanel);
      commentDisclosurePanel.setOpen(renderedComments == 0 || forceOpen);
      commentDisclosurePanel.setWidth("100%");
      add(createCommentPostPanel());
      add(commentDisclosurePanel);
    }
    if (layoutCallback != null) {
      layoutCallback.layoutComplete();
    }
  }

  private Widget createPageControllerPanel(final FlexTable mainPanel) {
    final IconButton nextPageImageButton = new IconButton(null, true, BaseImageBundle.images.next(), BaseImageBundle.images.next(),
        BaseImageBundle.images.next(), BaseImageBundle.images.next());
    nextPageImageButton.setSTYLE("commentToolBarButton");
    nextPageImageButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        if (pageNumber == lastPageNumber) {
          return;
        }
        pageNumber++;
        fetchPage();
      }
    });
    final IconButton previousPageImageButton = new IconButton(null, false, BaseImageBundle.images.previous(), BaseImageBundle.images.previous(),
        BaseImageBundle.images.previous(), BaseImageBundle.images.previous());
    previousPageImageButton.setSTYLE("commentToolBarButton");
    previousPageImageButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        if (pageNumber == 0) {
          return;
        }
        pageNumber--;
        fetchPage();
      }
    });
    final IconButton lastPageImageButton = new IconButton(null, false, BaseImageBundle.images.last(), BaseImageBundle.images.last(),
        BaseImageBundle.images.last(), BaseImageBundle.images.last());
    lastPageImageButton.setSTYLE("commentToolBarButton");
    lastPageImageButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        pageNumber = (int) lastPageNumber;
        fetchPage();
      }
    });
    final IconButton firstPageImageButton = new IconButton(null, false, BaseImageBundle.images.first(), BaseImageBundle.images.first(),
        BaseImageBundle.images.first(), BaseImageBundle.images.first());
    firstPageImageButton.setSTYLE("commentToolBarButton");
    firstPageImageButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        pageNumber = 0;
        fetchPage();
      }
    });
    if (lastPageNumber < 0) {
      firstPageImageButton.setEnabled(false);
      previousPageImageButton.setEnabled(false);
      nextPageImageButton.setEnabled(false);
      lastPageImageButton.setEnabled(false);
    }

    HorizontalPanel buttonPanel = new HorizontalPanel();
    buttonPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
    buttonPanel.add(firstPageImageButton);
    buttonPanel.add(previousPageImageButton);
    Label pageLabel = new Label("Page " + (pageNumber + 1) + " of " + (lastPageNumber + 1), false);
    if (lastPageNumber < 0) {
      pageLabel.setText("Page 1 of 1");
    }
    DOM.setStyleAttribute(pageLabel.getElement(), "margin", "0 5px 0 5px");
    buttonPanel.add(pageLabel);
    buttonPanel.add(nextPageImageButton);
    buttonPanel.add(lastPageImageButton);
    return buttonPanel;
  }

  private Widget createButtonPanel(final FlexTable mainPanel, final boolean forceOpen) {
    final IconButton reloadImageButton = new IconButton("Refresh", true, BaseImageBundle.images.refresh_16(), BaseImageBundle.images.refresh_16(),
        BaseImageBundle.images.refresh_16(), BaseImageBundle.images.refresh_disabled_16());
    reloadImageButton.setSTYLE("commentToolBarButton");
    reloadImageButton.setTitle("Refresh comments");
    reloadImageButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        BaseServiceCache.getService().getPageInfo(permissibleObject, Comment.class.getName(), pageSize, new AsyncCallback<PageInfo>() {
          public void onFailure(Throwable caught) {
          };

          public void onSuccess(PageInfo pageInfo) {
            numComments = pageInfo.getTotalRowCount();
            lastPageNumber = pageInfo.getLastPageNumber();
            pageCache.clear();
            fetchPage();
          };
        });
      }
    });

    final IconButton sortImageButton = new IconButton("Sort " + (sortDescending ? "Ascending" : "Descending"), true, BaseImageBundle.images.sort(),
        BaseImageBundle.images.sort(), BaseImageBundle.images.sort(), BaseImageBundle.images.sort());
    sortImageButton.setSTYLE("commentToolBarButton");
    sortImageButton.setTitle(sortDescending ? "Show oldest comments first" : "Show most recent comments first");
    sortImageButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        sortDescending = !sortDescending;
        // this could be optimized if we have all the pages, then we have all the data
        // we could do it all on the client
        pageCache.clear();
        fetchPage();
      }
    });

    IconButton flattenImageButton = null;
    if (flatten) {
      flattenImageButton = new IconButton("Hierarchy", true, BaseImageBundle.images.hierarchy(), BaseImageBundle.images.hierarchy(),
          BaseImageBundle.images.hierarchy(), BaseImageBundle.images.hierarchy());
      flattenImageButton.setTitle("Build a comment hierarchy");
    } else {
      flattenImageButton = new IconButton("Flatten", true, BaseImageBundle.images.flatten(), BaseImageBundle.images.flatten(),
          BaseImageBundle.images.flatten(), BaseImageBundle.images.flatten());
      flattenImageButton.setTitle("Flatten the comment hierarchy");
    }
    flattenImageButton.setSTYLE("commentToolBarButton");
    flattenImageButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        flatten = !flatten;
        loadCommentWidget(forceOpen);
      }
    });

    HorizontalPanel buttonPanel = new HorizontalPanel();
    buttonPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
    buttonPanel.add(createPageControllerPanel(mainPanel));
    Label spacer1 = new Label();
    buttonPanel.add(spacer1);
    buttonPanel.setCellWidth(spacer1, "20px");
    buttonPanel.add(reloadImageButton);
    buttonPanel.add(sortImageButton);
    buttonPanel.add(flattenImageButton);
    Label maxCommentDepthLabel = new Label("Max Depth", false);
    maxCommentDepthLabel.setTitle("Set the maximum depth of comments to show");
    Label spacer2 = new Label();
    buttonPanel.add(spacer2);
    buttonPanel.setCellWidth(spacer2, "20px");
    buttonPanel.add(maxCommentDepthLabel);
    buttonPanel.add(maxCommentDepthListBox);
    return buttonPanel;
  }

  private DisclosurePanel createCommentPostPanel() {
    DisclosurePanel postCommentDisclosurePanel = new DisclosurePanel("Post Comment");
    postCommentDisclosurePanel.setWidth("100%");
    postCommentDisclosurePanel.setOpen(true);
    VerticalPanel postCommentPanel = new VerticalPanel();
    postCommentPanel.setWidth("100%");
    // create text area for comment
    final TextArea commentTextArea = new TextArea();
    commentTextArea.setVisibleLines(3);
    commentTextArea.setWidth("500px");
    // create textfield for email address (if not logged in)
    final TextBox emailTextField = new TextBox();
    emailTextField.setVisibleLength(60);
    // create button panel
    HorizontalPanel buttonPanelWrapper = new HorizontalPanel();
    buttonPanelWrapper.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
    buttonPanelWrapper.setWidth("500px");
    HorizontalPanel buttonPanel = new HorizontalPanel();
    // create buttons
    final Button submitButton = new Button("Submit");
    submitButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        String commentStr = commentTextArea.getText();
        if (commentStr == null || "".equals(commentStr.trim())) {
          return;
        }
        Comment comment = new Comment();
        comment.setGlobalRead(true);
        comment.setOwner(permissibleObject.getOwner());
        comment.setAuthor(AuthenticationHandler.getInstance().getUser());
        comment.setComment(commentStr);
        comment.setParent(permissibleObject);
        comment.setEmail(emailTextField.getText());
        submitButton.setEnabled(false);
        submitComment(comment);
      }
    });
    final Button clearButton = new Button("Clear");
    clearButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        commentTextArea.setText("");
        submitButton.setEnabled(true);
      }
    });
    // add buttons
    buttonPanel.add(clearButton);
    buttonPanel.add(submitButton);
    buttonPanelWrapper.add(buttonPanel);
    // add panels
    if (AuthenticationHandler.getInstance().getUser() == null) {
      postCommentPanel.add(new Label("Email:"));
      postCommentPanel.add(emailTextField);
    }
    postCommentPanel.add(new Label("Comment:"));
    postCommentPanel.add(commentTextArea);
    postCommentPanel.add(buttonPanelWrapper);
    postCommentDisclosurePanel.setContent(postCommentPanel);
    return postCommentDisclosurePanel;
  }

  private void replyToComment(final Comment parentComment) {
    String replyPromptMessage = "Reply";
    if (parentComment.getAuthor() != null) {
      replyPromptMessage = "Reply To: " + parentComment.getAuthor().getUsername();
    } else if (!StringUtils.isEmpty(parentComment.getEmail())) {
      replyPromptMessage = "Reply To: " + parentComment.getEmail();
    }
    PromptDialogBox dialog = new PromptDialogBox(replyPromptMessage, "Submit", null, "Cancel", false, true);
    dialog.setAllowKeyboardEvents(false);
    VerticalPanel replyPanel = new VerticalPanel();

    final TextArea textArea = new TextArea();
    textArea.setCharacterWidth(60);
    textArea.setVisibleLines(4);
    final TextBox emailTextBox = new TextBox();
    if (AuthenticationHandler.getInstance().getUser() == null) {
      replyPanel.add(new Label("Email:"));
      replyPanel.add(emailTextBox);
    }
    replyPanel.add(textArea);

    dialog.setFocusWidget(textArea);
    dialog.setContent(replyPanel);
    dialog.setValidatorCallback(new IDialogValidatorCallback() {
      public boolean validate() {
        if (textArea.getText() == null || "".equals(textArea.getText())) {
          MessageDialogBox dialog = new MessageDialogBox("Error", "Comment is blank.", false, true, true);
          dialog.center();
          return false;
        }
        return true;
      }
    });
    dialog.setCallback(new IDialogCallback() {
      public void okPressed() {
        Comment newComment = new Comment();
        newComment.setGlobalRead(true);
        newComment.setOwner(permissibleObject.getOwner());
        newComment.setAuthor(AuthenticationHandler.getInstance().getUser());
        newComment.setComment(textArea.getText());
        newComment.setParent(permissibleObject);
        newComment.setParentComment(parentComment);
        newComment.setEmail(emailTextBox.getText());
        submitComment(newComment);
      }

      public void cancelPressed() {
      }
    });
    dialog.center();
  }

  private List<PermissibleObject> sortComments(List<PermissibleObject> comments) {
    List<Comment> commentSet = new ArrayList<Comment>();

    for (PermissibleObject obj : comments) {
      Comment comment = (Comment) obj;
      commentSet.add(comment);
      Comment parent = comment.getParentComment();
      do {
        if (parent != null) {
          if (!commentSet.contains(parent)) {
            commentSet.add(parent);
          }
          parent = parent.getParentComment();
        }
      } while (parent != null);
    }

    // create bare nodes for each element
    PermissibleObjectTreeNode rootNode = new PermissibleObjectTreeNode();

    for (Comment comment : commentSet) {
      PermissibleObjectTreeNode node = new PermissibleObjectTreeNode();
      node.setObject(comment);
      if (comment.getParentComment() == null) {
        if (!rootNode.getChildren().containsKey(comment)) {
          rootNode.getChildren().put(comment, node);
        }
      } else {
        // try to find parent in rootNode tree
        PermissibleObjectTreeNode parent = findParentCommentNode(rootNode, node);
        if (parent == null) {
          // this nodes parent cannot be found, let's add all of his parents
          List<Comment> parentComments = new ArrayList<Comment>();
          Comment parentComment = comment.getParentComment();
          do {
            if (parentComment != null) {
              parentComments.add(parentComment);
              parentComment = parentComment.getParentComment();
            }
          } while (parent != null);
          if (parentComments.size() == 0) {
            rootNode.getChildren().put(comment, node);
          } else {
            // reverse the order of the list and add/find existing parents
            Collections.reverse(parentComments);
            for (Comment myParentComment : parentComments) {
              PermissibleObjectTreeNode myParentCommentNode = new PermissibleObjectTreeNode();
              myParentCommentNode.setObject(myParentComment);
              PermissibleObjectTreeNode parentParent = findParentCommentNode(rootNode, myParentCommentNode);
              if (parentParent == null) {
                rootNode.getChildren().put(myParentComment, myParentCommentNode);
              } else {
                if (!parentParent.getChildren().containsKey(myParentComment)) {
                  parentParent.getChildren().put(myParentComment, myParentCommentNode);
                }
              }
            }
            // we better find it now
            parent = findParentCommentNode(rootNode, node);
            parent.getChildren().put(comment, node);
          }
        } else {
          if (!parent.getChildren().containsKey(comment)) {
            parent.getChildren().put(comment, node);
          }
        }
      }
    }

    // march the tree
    ArrayList<PermissibleObject> list = new ArrayList<PermissibleObject>();
    marchTree(list, rootNode);

    return list;
  }

  private void marchTree(List<PermissibleObject> comments, PermissibleObjectTreeNode node) {
    if (node.getObject() != null) {
      comments.add(node.getObject());
    }

    // let's sort the children so the list makes sense
    List<PermissibleObject> permissibleObjects = new ArrayList<PermissibleObject>(node.getChildren().keySet());
    Collections.sort(permissibleObjects);

    for (PermissibleObject object : permissibleObjects) {
      marchTree(comments, node.getChildren().get(object));
    }
  }

  private PermissibleObjectTreeNode findParentCommentNode(PermissibleObjectTreeNode rootNode, PermissibleObjectTreeNode node) {
    if (node.getObject().equals(rootNode.getObject())) {
      return rootNode;
    }
    for (PermissibleObject obj : rootNode.getChildren().keySet()) {
      if (obj.equals(((Comment) node.getObject()).getParentComment())) {
        return rootNode.getChildren().get(obj);
      }
      PermissibleObjectTreeNode possibleParent = findParentCommentNode(rootNode.getChildren().get(obj), node);
      if (possibleParent != null) {
        return possibleParent;
      }
    }
    return null;
  }

  private int getCommentDepth(Comment comment) {
    int depth = 0;
    Comment parent = comment.getParentComment();
    while (parent != null) {
      depth++;
      parent = parent.getParentComment();
    }
    return depth;
  }

  private void prefetchPage(int pageNumber) {
    Page<PermissibleObject> page = pageCache.get(pageNumber);
    if (page == null && pageNumber >= 0 && pageNumber <= lastPageNumber) {
      BaseServiceCache.getService().getPage(permissibleObject, Comment.class.getName(), "id", sortDescending, pageNumber, pageSize, preFetchPageCallback);
    }
  }

  private void prefetchPages() {
    // fetch the first page & last page (for people who jump to beginning/end)
    prefetchPage(0);
    prefetchPage((int) lastPageNumber);
    // try to fetch a few pages before and after the current page and cache them
    prefetchPage(pageNumber + 1);
    prefetchPage(pageNumber + 2);
    prefetchPage(pageNumber + 3);
    prefetchPage(pageNumber + 4);
    prefetchPage(pageNumber + 5);
    prefetchPage(pageNumber - 1);
    prefetchPage(pageNumber - 2);
    prefetchPage(pageNumber - 3);
    prefetchPage(pageNumber - 4);
    prefetchPage(pageNumber - 5);
  }

  private void fetchPage() {
    if (paginate) {
      Page<PermissibleObject> page = pageCache.get(pageNumber);
      if (page != null) {
        pageCallback.onSuccess(page);
      } else {
        BaseServiceCache.getService().getPage(permissibleObject, Comment.class.getName(), "id", sortDescending, pageNumber, pageSize, pageCallback);
      }
    } else {
      CursorUtils.setBusyCursor(CommentWidget.this);
      BaseServiceCache.getService().getPermissibleObjects(permissibleObject, Comment.class.getName(), allCommentsCallback);
    }
  }

  private void submitComment(final Comment comment) {
    CursorUtils.setBusyCursor(this);
    BaseServiceCache.getService().getPageInfo(permissibleObject, Comment.class.getName(), pageSize, new AsyncCallback<PageInfo>() {
      public void onFailure(Throwable caught) {
        CursorUtils.setDefaultCursor(CommentWidget.this);
      }

      public void onSuccess(PageInfo pageInfo) {
        CursorUtils.setDefaultCursor(CommentWidget.this);
        numComments = pageInfo.getTotalRowCount();
        lastPageNumber = pageInfo.getLastPageNumber();
        BaseServiceCache.getService().submitComment(comment, submitCommentCallback);
      }
    });
  }

  private void approveComment(Comment comment) {
    BaseServiceCache.getService().approveComment(comment, approveCallback);
  }

  private void deleteComment(final Comment comment) {
    BaseServiceCache.getService().getPageInfo(permissibleObject, Comment.class.getName(), pageSize, new AsyncCallback<PageInfo>() {
      public void onFailure(Throwable caught) {
      };

      public void onSuccess(PageInfo pageInfo) {
        numComments = pageInfo.getTotalRowCount();
        lastPageNumber = pageInfo.getLastPageNumber();
        BaseServiceCache.getService().deleteComment(comment, deleteCommentCallback);
      };
    });
  }

  public boolean isFlatten() {
    return flatten;
  }

  public void setFlatten(boolean flatten) {
    this.flatten = flatten;
    loadCommentWidget(true);
  }
}
TOP

Related Classes of org.damour.base.client.ui.comment.CommentWidget

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.