/**
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.waveprotocol.box.webclient.search;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import org.waveprotocol.wave.client.account.Profile;
import org.waveprotocol.wave.client.common.safehtml.SafeHtml;
import org.waveprotocol.wave.client.common.safehtml.SafeHtmlBuilder;
import org.waveprotocol.wave.client.uibuilder.BuilderHelper;
/**
* DOM implementation of a digest view.
*
* @author hearnden@google.com (David Hearnden)
*/
public final class DigestDomImpl implements DigestView {
/** HTML attribute used to hold an id unique within digest widgets. */
static String DIGEST_ID_ATTRIBUTE = "di";
/** Resources used by this widget. */
interface Resources extends ClientBundle {
/** CSS */
@Source("mock/digest.css")
Css css();
}
interface Css extends CssResource {
String digest();
String inner();
String avatars();
String avatar();
String info();
String unread();
String unreadCount();
String selected();
}
@UiField(provided = true)
final static Css css = SearchPanelResourceLoader.getDigest().css();
interface Binder extends UiBinder<Element, DigestDomImpl> {
}
private final static Binder BINDER = GWT.create(Binder.class);
private static int idCounter;
private final SearchPanelWidget container;
private final Element self;
@UiField
Element avatars;
@UiField
Element title;
@UiField
Element snippet;
@UiField
Element time;
@UiField
Element msgs;
DigestDomImpl(SearchPanelWidget container) {
this.container = container;
this.self = BINDER.createAndBindUi(this);
self.setAttribute(BuilderHelper.KIND_ATTRIBUTE, "digest");
self.setAttribute(DIGEST_ID_ATTRIBUTE, "D" + idCounter++);
}
@Override
public void remove() {
self.removeFromParent();
container.onDigestRemoved(this);
}
/** @return an id of this widget, unique within the space of digest widgets. */
String getId() {
return self.getAttribute(DIGEST_ID_ATTRIBUTE);
}
/** Restores this object to a post-constructor state. */
void reset() {
avatars.setInnerHTML("");
title.setInnerText("");
snippet.setInnerText("");
time.setInnerText("");
msgs.setInnerHTML("");
self.removeClassName(css.selected());
}
@Override
public void setAvatars(Iterable<Profile> profiles) {
SafeHtmlBuilder html = new SafeHtmlBuilder();
for (Profile profile : profiles) {
renderAvatar(html, profile);
}
avatars.setInnerHTML(html.toSafeHtml().asString());
}
@Override
public void setTitleText(String title) {
this.title.setInnerText(title);
}
@Override
public void setSnippet(String snippet) {
this.snippet.setInnerText(snippet);
}
@Override
public void setTimestamp(String time) {
this.time.setInnerText(time);
}
@Override
public void setMessageCounts(int unread, int total) {
if (unread == 0) {
msgs.setInnerHTML(renderReadMessages(total).asString());
title.removeClassName(css.unread());
time.removeClassName(css.unread());
} else {
msgs.setInnerHTML(renderUnreadMessages(unread, total).asString());
title.addClassName(css.unread());
time.addClassName(css.unread());
}
}
private SafeHtml renderUnreadMessages(int unread, int total) {
SafeHtmlBuilder html = new SafeHtmlBuilder();
html.appendHtmlConstant("<span class='" + css.unreadCount() + "'>");
html.appendHtmlConstant(String.valueOf(unread));
html.appendHtmlConstant("</span>");
html.appendHtmlConstant(" of ");
html.appendHtmlConstant(String.valueOf(total));
return html.toSafeHtml();
}
private SafeHtml renderReadMessages(int total) {
SafeHtmlBuilder html = new SafeHtmlBuilder();
html.appendHtmlConstant(String.valueOf(total));
html.appendHtmlConstant(" msgs");
return html.toSafeHtml();
}
private void renderAvatar(SafeHtmlBuilder html, Profile profile) {
// URL is trusted to be attribute safe (i.e., no ' or ")
String url = profile.getImageUrl();
String name = profile.getFullName();
html.appendHtmlConstant("<img class='" + css.avatar() + "' src='");
html.appendHtmlConstant(url);
html.appendHtmlConstant("' alt='");
html.appendEscaped(name);
html.appendHtmlConstant("' title='");
html.appendEscaped(name);
html.appendHtmlConstant("'>");
}
@Override
public void select() {
self.addClassName(css.selected());
}
@Override
public void deselect() {
self.removeClassName(css.selected());
}
Element getElement() {
return self;
}
}