diff options
Diffstat (limited to 'gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java')
-rw-r--r-- | gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java | 157 |
1 files changed, 143 insertions, 14 deletions
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java index 00597238b3..5dcccb04b5 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java @@ -14,16 +14,26 @@ package com.google.gerrit.client; +import com.google.gerrit.client.account.AccountInfo; +import com.google.gerrit.client.changes.Util; import com.google.gerrit.client.rpc.RestApi; -import com.google.gerrit.reviewdb.client.Account; -import com.google.gwt.event.dom.client.ErrorEvent; -import com.google.gwt.event.dom.client.ErrorHandler; +import com.google.gwt.event.dom.client.LoadEvent; +import com.google.gwt.event.dom.client.LoadHandler; +import com.google.gwt.event.dom.client.MouseOutEvent; +import com.google.gwt.event.dom.client.MouseOutHandler; +import com.google.gwt.event.dom.client.MouseOverEvent; +import com.google.gwt.event.dom.client.MouseOverHandler; +import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Image; +import com.google.gwt.user.client.ui.UIObject; public class AvatarImage extends Image { + public AvatarImage() { + } + /** A default sized avatar image. */ - public AvatarImage(Account.Id account) { + public AvatarImage(AccountInfo account) { this(account, 0); } @@ -35,30 +45,66 @@ public class AvatarImage extends Image { * on the avatar provider. A size <= 0 indicates to let the provider * decide a default size. */ - public AvatarImage(Account.Id account, int size) { - super(url(account, size)); + public AvatarImage(AccountInfo account, int size) { + this(account, size, true); + } + + /** + * An avatar image for the given account using the requested size. + * + * @param account The account in which we are interested + * @param size A requested size. Note that the size can be ignored depending + * on the avatar provider. A size <= 0 indicates to let the provider + * decide a default size. + * @param addPopup show avatar popup with user info on hovering over the + * avatar image + */ + public AvatarImage(AccountInfo account, int size, boolean addPopup) { + setAccount(account, size, addPopup); + } + + public void setAccount(AccountInfo account, int size, boolean addPopup) { + setUrl(isGerritServer(account) ? getGerritServerAvatarUrl() : + url(account.email(), size)); + setVisible(false); if (size > 0) { // If the provider does not resize the image, force it in the browser. setSize(size + "px", size + "px"); } - addErrorHandler(new ErrorHandler() { + addLoadHandler(new LoadHandler() { @Override - public void onError(ErrorEvent event) { - // We got a 404, don't bother showing the image. Either the user doesn't - // have an avatar or there is no avatar provider plugin installed. - setVisible(false); + public void onLoad(LoadEvent event) { + setVisible(true); } }); + + if (addPopup) { + PopupHandler popupHandler = new PopupHandler(account, this); + addMouseOverHandler(popupHandler); + addMouseOutHandler(popupHandler); + } } - private static String url(Account.Id id, int size) { + private static boolean isGerritServer(AccountInfo account) { + return account._account_id() == 0 + && Util.C.messageNoAuthor().equals(account.name()); + } + + private static String getGerritServerAvatarUrl() { + return Gerrit.RESOURCES.gerritAvatar().getSafeUri().asString(); + } + + private static String url(String email, int size) { + if (email == null) { + return ""; + } String u; - if (Gerrit.isSignedIn() && id.equals(Gerrit.getUserAccount().getId())) { + if (Gerrit.isSignedIn() && email.equals(Gerrit.getUserAccount().getPreferredEmail())) { u = "self"; } else { - u = id.toString(); + u = email; } RestApi api = new RestApi("/accounts/").id(u).view("avatar"); if (size > 0) { @@ -66,4 +112,87 @@ public class AvatarImage extends Image { } return api.url(); } + + private class PopupHandler implements MouseOverHandler, MouseOutHandler { + private final AccountInfo account; + private final UIObject target; + + private UserPopupPanel popup; + private Timer showTimer; + private Timer hideTimer; + + public PopupHandler(AccountInfo account, UIObject target) { + this.account = account; + this.target = target; + } + + private UserPopupPanel createPopupPanel(AccountInfo account) { + UserPopupPanel popup = new UserPopupPanel(account, false, false); + popup.addDomHandler(new MouseOverHandler() { + @Override + public void onMouseOver(MouseOverEvent event) { + scheduleShow(); + } + }, MouseOverEvent.getType()); + popup.addDomHandler(new MouseOutHandler() { + @Override + public void onMouseOut(MouseOutEvent event) { + scheduleHide(); + } + }, MouseOutEvent.getType()); + return popup; + } + + @Override + public void onMouseOver(MouseOverEvent event) { + scheduleShow(); + } + + @Override + public void onMouseOut(MouseOutEvent event) { + scheduleHide(); + } + + private void scheduleShow() { + if (hideTimer != null) { + hideTimer.cancel(); + hideTimer = null; + } + if ((popup != null && popup.isShowing() && popup.isVisible()) + || showTimer != null) { + return; + } + showTimer = new Timer() { + @Override + public void run() { + if (popup == null) { + popup = createPopupPanel(account); + } + if (!popup.isShowing() || !popup.isVisible()) { + popup.showRelativeTo(target); + } + + } + }; + showTimer.schedule(600); + } + + private void scheduleHide() { + if (showTimer != null) { + showTimer.cancel(); + showTimer = null; + } + if (popup == null || !popup.isShowing() || !popup.isVisible() + || hideTimer != null) { + return; + } + hideTimer = new Timer() { + @Override + public void run() { + popup.hide(); + } + }; + hideTimer.schedule(50); + } + } } |