/*
* Copyright (c) 2009-2011 Lockheed Martin Corporation
*
* 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.eurekastreams.web.client.ui.common.stream.attach.bookmark;
import org.eurekastreams.commons.client.ActionRequestImpl;
import org.eurekastreams.server.domain.stream.LinkInformation;
import org.eurekastreams.web.client.events.EventBus;
import org.eurekastreams.web.client.events.MessageAttachmentChangedEvent;
import org.eurekastreams.web.client.events.Observer;
import org.eurekastreams.web.client.events.ParseLinkEvent;
import org.eurekastreams.web.client.events.ShowNotificationEvent;
import org.eurekastreams.web.client.events.errors.ErrorPostingMessageToNullScopeEvent;
import org.eurekastreams.web.client.ui.Session;
import org.eurekastreams.web.client.ui.common.LabeledTextBox;
import org.eurekastreams.web.client.ui.common.notifier.Notification;
import org.eurekastreams.web.client.ui.common.stream.thumbnail.ThumbnailSelectorComposite;
import org.eurekastreams.web.client.ui.pages.master.StaticResourceBundle;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
/**
* Add link panel.
*/
public class AddLinkComposite extends FlowPanel
{
/** Add link button. */
private final Label addLink = new Label("attach link");
/** Add link button. */
private final Label fetchLink = new Label("Go");
/** The add link panel. */
private final FlowPanel addPanel = new FlowPanel();
/** The URL to the link. */
private final LabeledTextBox linkUrl = new LabeledTextBox("http://");
/** The display link panel. */
private final FlowPanel displayPanel = new FlowPanel();
/** Thumbnail selector. */
private final ThumbnailSelectorComposite selector = new ThumbnailSelectorComposite();
/** Link URL. */
private final Label linkUrlDisplay = new Label();
/** The title link. */
private final FlowPanel titleLink = new FlowPanel();
/** Link Description. */
private final Label linkDesc = new Label();
/** The close button. */
private final Label closeDisplayButton = new Label(StaticResourceBundle.INSTANCE.coreCss().close());
/** The close button. */
private final Label closeAddButton = new Label(StaticResourceBundle.INSTANCE.coreCss().close());
/** Text box. */
private final TextBox title = new TextBox();
/** The last fetched links url. */
private String fetchedLink = "";
/** Max length of title. */
private static final int MAX_LENGTH = 50;
/** Message for URLs which fail on getting parsed link information. */
private static final String UNVERIFIED_URL_MESSAGE = "URL may be invalid. "
+ "Please confirm it was entered correctly.";
/** Message for URLs which returned missing link information. */
private static final String INCOMPLETE_INFO_URL_MESSAGE = "Details about URL could not be retrieved. "
+ "Please confirm it was entered correctly.";
/**
* Constructor.
*/
public AddLinkComposite()
{
// add the three main widgets
add(addLink);
add(displayPanel);
add(addPanel);
addStyleName(StaticResourceBundle.INSTANCE.coreCss().attachLinkContainer());
// only one is visible at a time, so hide the others
addPanel.setVisible(false);
displayPanel.setVisible(false);
addLink.addStyleName(StaticResourceBundle.INSTANCE.coreCss().showAttachLinkPanel());
// -- Setup the add link panel (field to enter URL) --
addPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().attachLink());
closeAddButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().close());
addPanel.add(closeAddButton);
Label addLinkLabel = new Label("Add Link");
addLinkLabel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().title());
addPanel.add(addLinkLabel);
SimplePanel boxWrapper = new SimplePanel();
boxWrapper.addStyleName(StaticResourceBundle.INSTANCE.coreCss().boxWrapper());
boxWrapper.add(linkUrl);
addPanel.add(fetchLink);
addPanel.add(boxWrapper);
fetchLink.addStyleName(StaticResourceBundle.INSTANCE.coreCss().addButtonSubmit());
// -- Setup the link display panel (thumbnail selector, field to update title) --
title.addStyleName(StaticResourceBundle.INSTANCE.coreCss().attachLinkTitleEntry());
linkUrlDisplay.addStyleName(StaticResourceBundle.INSTANCE.coreCss().url());
linkDesc.addStyleName(StaticResourceBundle.INSTANCE.coreCss().metaDescription());
FlowPanel linkInfoPanel = new FlowPanel();
linkInfoPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().messageLink());
linkInfoPanel.add(title);
linkInfoPanel.add(linkUrlDisplay);
linkInfoPanel.add(linkDesc);
closeDisplayButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().close());
displayPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().linkPanel());
displayPanel.add(closeDisplayButton);
displayPanel.add(selector);
displayPanel.add(linkInfoPanel);
displayPanel.add(selector.getPagingControls());
EventBus eventBus = Session.getInstance().getEventBus();
eventBus.addObserver(ParseLinkEvent.getEvent(), new Observer<ParseLinkEvent>()
{
public void update(final ParseLinkEvent event)
{
onAddLinkClicked();
linkUrl.setText(event.getUrl());
fetchLink.addStyleName(StaticResourceBundle.INSTANCE.coreCss().verifyingLink());
fetchLink(event.getUrl());
}
});
eventBus.addObserver(MessageAttachmentChangedEvent.class, new Observer<MessageAttachmentChangedEvent>()
{
public void update(final MessageAttachmentChangedEvent evt)
{
if (evt.getAttachment() != null && evt.getAttachment() instanceof Bookmark)
{
onLinkAdded(((Bookmark) evt.getAttachment()).getLinkInformation());
}
else
{
onLinkAdded(null);
}
}
});
eventBus.addObserver(new ErrorPostingMessageToNullScopeEvent(),
new Observer<ErrorPostingMessageToNullScopeEvent>()
{
public void update(final ErrorPostingMessageToNullScopeEvent event)
{
fetchLink.removeStyleName(StaticResourceBundle.INSTANCE.coreCss().verifyingLink());
}
});
fetchLink.addClickHandler(new ClickHandler()
{
public void onClick(final ClickEvent event)
{
fetchLink.addStyleName(StaticResourceBundle.INSTANCE.coreCss().verifyingLink());
fetchLink(linkUrl.getText());
}
});
addLink.addClickHandler(new ClickHandler()
{
public void onClick(final ClickEvent event)
{
onAddLinkClicked();
}
});
closeDisplayButton.addClickHandler(new ClickHandler()
{
public void onClick(final ClickEvent event)
{
close();
}
});
closeAddButton.addClickHandler(new ClickHandler()
{
public void onClick(final ClickEvent event)
{
close();
}
});
}
/**
* Shows the add link form.
*/
public void onAddLinkClicked()
{
addLink.setVisible(false);
addPanel.setVisible(true);
linkUrl.reset();
}
/**
* @return true if a link is attached.
*/
public boolean hasAttachment()
{
return displayPanel.isVisible();
}
/**
* Close the link.
*/
public void close()
{
fetchedLink = "";
Session.getInstance().getEventBus().notifyObservers(new MessageAttachmentChangedEvent(null));
}
/**
* Called when a link is added to the message.
*
* @param link
* the link that was added.
*/
public void onLinkAdded(final LinkInformation link)
{
linkUrl.setText("");
linkUrl.checkBox();
LinkInformation addedLink = link;
if (null == addedLink)
{
addedLink = new LinkInformation();
}
addPanel.setVisible(false);
fetchLink.removeStyleName(StaticResourceBundle.INSTANCE.coreCss().verifyingLink());
displayPanel.setVisible(null != link);
addLink.setVisible(null == link);
selector.setLink(addedLink);
if (!addedLink.getImageUrls().isEmpty())
{
displayPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().hasThumbnail());
}
linkUrlDisplay.setText("source: " + addedLink.getSource());
title.setVisibleLength(MAX_LENGTH);
title.setValue(addedLink.getTitle());
title.addBlurHandler(new BlurHandler()
{
public void onBlur(final BlurEvent event)
{
// This check is a workaround for the real problem, which is that the blur handler is getting wired up
// multiple times (once on the first time the user clicks 'add link' and once when the activity is
// posted and everything is being cleared out). Maybe this control will get redesigned when
// PostToStreamComposite gets refactored from MVC to the current design.
if (link != null)
{
link.setTitle(title.getValue());
}
}
});
linkDesc.setText(addedLink.getDescription());
}
/**
* Fetch link.
*
* @param inLinkUrl
* link url.
*/
public void fetchLink(final String inLinkUrl)
{
// very basic url validation
final EventBus eventBus = Session.getInstance().getEventBus();
if (inLinkUrl == null || inLinkUrl.isEmpty() || !inLinkUrl.contains("://"))
{
ErrorPostingMessageToNullScopeEvent error = new ErrorPostingMessageToNullScopeEvent();
error.setErrorMsg("You must supply a valid url (example: http://www.example.com)");
eventBus.notifyObservers(error);
}
else if (inLinkUrl != fetchedLink)
{
Session.getInstance()
.getActionProcessor()
.makeRequest(new ActionRequestImpl<LinkInformation>("getParsedLinkInformation", inLinkUrl),
new AsyncCallback<LinkInformation>()
{
/* implement the async call back methods */
public void onFailure(final Throwable caught)
{
LinkInformation linkInformation = new LinkInformation();
linkInformation.setTitle(inLinkUrl);
linkInformation.setUrl(inLinkUrl);
MessageAttachmentChangedEvent event = new MessageAttachmentChangedEvent(
new Bookmark(linkInformation));
eventBus.notifyObservers(event);
eventBus.notifyObservers(new ShowNotificationEvent(new Notification(
UNVERIFIED_URL_MESSAGE)));
}
public void onSuccess(final LinkInformation result)
{
MessageAttachmentChangedEvent event = new MessageAttachmentChangedEvent(
new Bookmark(result));
boolean titleBlank = result.getTitle() == null || result.getTitle().isEmpty();
if (titleBlank)
{
result.setTitle(result.getUrl());
}
eventBus.notifyObservers(event);
// no reason to show any errors
// if (titleBlank
// && (result.getDescription() == null || result.getDescription().isEmpty())
// && result.getImageUrls().isEmpty())
// {
// eventBus.notifyObservers(new ShowNotificationEvent(new Notification(
// INCOMPLETE_INFO_URL_MESSAGE)));
// }
}
});
}
fetchedLink = inLinkUrl;
}
}