package org.limewire.ui.swing.home; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.net.URL; import javax.swing.BorderFactory; import javax.swing.JScrollPane; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import org.jdesktop.swingx.JXPanel; import org.limewire.concurrent.FutureEvent; import org.limewire.core.api.connection.GnutellaConnectionManager; import org.limewire.inject.LazySingleton; import org.limewire.listener.EventListener; import org.limewire.listener.SwingEDTEvent; import org.limewire.ui.swing.browser.Browser; import org.limewire.ui.swing.browser.BrowserUtils; import org.limewire.ui.swing.browser.UriAction; import org.limewire.ui.swing.components.HTMLPane; import org.limewire.ui.swing.components.HTMLPane.LoadResult; import org.limewire.ui.swing.nav.NavCategory; import org.limewire.ui.swing.nav.Navigator; import org.limewire.ui.swing.util.NativeLaunchUtils; import org.limewire.ui.swing.util.SwingUtils; import org.mozilla.browser.MozillaInitialization; import org.mozilla.browser.MozillaPanel.VisibilityMode; import com.google.inject.Inject; /** The main home page.*/ @LazySingleton public class HomePanel extends JXPanel { private static final String DEFAULT_URL = "about:blank"; private final Browser browser; private final HTMLPane fallbackBrowser; private final GnutellaConnectionManager gnutellaConnectionManager; private boolean loadedOnce = false; private int retryCount = 0; private boolean firstRequest = true; private long initialLoadTime = -1; @Inject public HomePanel(final Navigator navigator, GnutellaConnectionManager gnutellaConnectionManager) { this.gnutellaConnectionManager = gnutellaConnectionManager; setPreferredSize(new Dimension(500, 500)); setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1; gbc.weighty = 1; if(MozillaInitialization.isInitialized()) { // Hide the page when the browser goes away. addComponentListener(new ComponentAdapter() { @Override public void componentHidden(ComponentEvent e) { browser.load("about:blank"); } }); BrowserUtils.addTargetedUrlAction("_lwHome", new UriAction() { @Override public boolean uriClicked(final TargetedUri targetedUrl) { SwingUtils.invokeNowOrLater(new Runnable() { @Override public void run() { navigator.getNavItem(NavCategory.LIMEWIRE, HomeMediator.NAME).select(); load(targetedUrl.getUri()); } }); return true; } }); browser = new Browser(VisibilityMode.FORCED_HIDDEN, VisibilityMode.FORCED_HIDDEN, VisibilityMode.DEFAULT) { @Override public void pageLoadStopped(final boolean failed) { super.pageLoadStopped(failed); SwingUtils.invokeNowOrLater(new Runnable() { @Override public void run() { pageLoadFinished(!failed); } }); } }; fallbackBrowser = null; add(browser, gbc); } else { browser = null; fallbackBrowser = new HTMLPane(); fallbackBrowser.addHyperlinkListener(new HyperlinkListener() { @Override public void hyperlinkUpdate(HyperlinkEvent e) { if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { NativeLaunchUtils.openURL(e.getURL().toExternalForm()); } } }); JScrollPane scroller = new JScrollPane(fallbackBrowser, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scroller.setBorder(BorderFactory.createEmptyBorder()); add(scroller, gbc); } } private boolean isRequestInProgress() { if(MozillaInitialization.isInitialized()) { return browser.isRequestInProgress(); } else { return fallbackBrowser.isRequestInProgress(); } } /** Notification that a page finished loading. */ private void pageLoadFinished(boolean success) { if(!success) { reloadDefaultUrlIfPossibleAndNeeded(); } } /** * Reloads the default URL, with some extra parameters, if we need to. */ private void reloadDefaultUrlIfPossibleAndNeeded() { // based on: // * if the browser is showing // * if the first request was already sent succesfully // * if there's no active request already // * if the retryCount is below 5 (we don't want to hammer) // * if we tried to load atleast once // * if the last request was successful // * if our current strength indicates we're online if (isShowing() && firstRequest && !isRequestInProgress() && retryCount < 5 && loadedOnce && !isLastRequestSuccessful() && gnutellaConnectionManager.getConnectionStrength().isOnline()) { retryCount++; long delay = System.currentTimeMillis() - initialLoadTime; load(DEFAULT_URL + "?rd=" + delay + "&rc=" + retryCount); } } /** Returns true if the last request was succesful. */ private boolean isLastRequestSuccessful() { if(MozillaInitialization.isInitialized()) { return browser.isLastRequestSuccessful(); } else { return fallbackBrowser.isLastRequestSuccessful(); } } public void loadDefaultUrl() { load(DEFAULT_URL); } public void load(String url) { loadedOnce = true; if(firstRequest) { if(isLastRequestSuccessful()) { firstRequest = false; } else { if(initialLoadTime == -1) { initialLoadTime = System.currentTimeMillis(); } } } if(MozillaInitialization.isInitialized()) { browser.load(url); } else { URL bgImage = HomePanel.class.getResource("/org/limewire/ui/swing/mainframe/resources/icons/static_pages/body_bg.png"); URL topImage = HomePanel.class.getResource("/org/limewire/ui/swing/mainframe/resources/icons/static_pages/header_logo.png"); String offlinePage = "<html><head><style type=\"text/css\">* {margin: 0; padding: 0;} body {background: #EAEAEA url(\""+ bgImage.toExternalForm() + "\") repeat-x left top; font-family: Arial, sans-serif;}table#layout tr td#header { background: url(\"" + topImage.toExternalForm() + "\") no-repeat center top;}table#layout tr td h2 { font-size: 16px; margin: 0 0 8px 0; color: #807E7E;}table#layout tr td p { font-size: 11px; color: #931F22;}</style></head><body><center> <table id=\"layout\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"400\" style=\"margin: 46px 0 0 0\"> <tr valign=\"top\"> <td id=\"header\" height=\"127\" align=\"center\"></td> </tr> <tr valign=\"top\"> <td align=\"center\"> <h2>You are offline</h2> <p>Please check your internet connection.</p> </td> </tr> </table></center></body></html>"; fallbackBrowser.setPageAsynchronous(url, offlinePage).addFutureListener(new EventListener<FutureEvent<LoadResult>>() { @SwingEDTEvent public void handleEvent(FutureEvent<LoadResult> event) { pageLoadFinished(event.getResult() == LoadResult.SERVER_PAGE); } }); } } /** * Loads "about:blank" in the browser if Mozilla is initialized. */ public void loadBlank(){ if (MozillaInitialization.isInitialized()) { browser.load("about:blank"); } } }