com.google.livingstories.client.lsp.views.OverviewPage.java Source code

Java tutorial

Introduction

Here is the source code for com.google.livingstories.client.lsp.views.OverviewPage.java

Source

/**
 * Copyright 2010 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 com.google.livingstories.client.lsp.views;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.livingstories.client.ContentItemTypesBundle;
import com.google.livingstories.client.ContentRpcService;
import com.google.livingstories.client.ContentRpcServiceAsync;
import com.google.livingstories.client.DisplayContentItemBundle;
import com.google.livingstories.client.FilterSpec;
import com.google.livingstories.client.LivingStoryRpcService;
import com.google.livingstories.client.LivingStoryRpcServiceAsync;
import com.google.livingstories.client.lsp.ContentRenderer;
import com.google.livingstories.client.lsp.FilterWidget;
import com.google.livingstories.client.lsp.LspContentItemListWidget;
import com.google.livingstories.client.lsp.Page;
import com.google.livingstories.client.lsp.RecentEventsList;
import com.google.livingstories.client.lsp.ThemeListWidget;
import com.google.livingstories.client.lsp.event.BlockToggledEvent;
import com.google.livingstories.client.lsp.event.EventBus;
import com.google.livingstories.client.ui.AnchoredPanel;
import com.google.livingstories.client.ui.FCCommentsBox;
import com.google.livingstories.client.ui.UpdateCountWidget;
import com.google.livingstories.client.util.HistoryManager;
import com.google.livingstories.client.util.LivingStoryControls;
import com.google.livingstories.client.util.LivingStoryData;
import com.google.livingstories.client.util.HistoryManager.HistoryPages;

import java.util.Map;

/**
 * Page that displays the summary and the content grid.
 */
public class OverviewPage extends Page {
    private static OverviewPageUiBinder uiBinder = GWT.create(OverviewPageUiBinder.class);

    interface OverviewPageUiBinder extends UiBinder<Widget, OverviewPage> {
    }

    private static final String SCROLL_POSITION_STATE = "sp";

    private final ContentRpcServiceAsync contentService = GWT.create(ContentRpcService.class);
    private final LivingStoryRpcServiceAsync livingStoryService = GWT.create(LivingStoryRpcService.class);

    @UiField
    Label title;
    @UiField
    UpdateCountWidget updateCount;
    @UiField
    SimplePanel summary;
    @UiField
    ThemeListWidget themeList;
    @UiField
    FilterWidget filterList;
    @UiField
    LspContentItemListWidget contentItemList;
    @UiField
    AnchoredPanel rightPanel;
    @UiField
    RecentEventsList recentEvents;
    @UiField
    FCCommentsBox comments;

    private HandlerRegistration toggleEventHandler;

    public OverviewPage() {
        initWidget(uiBinder.createAndBindUi(this));

        title.setText(LivingStoryData.getLivingStoryTitle());
        updateCount.load(LivingStoryData.getLivingStoryId(), LivingStoryData.getLastVisitDate());

        summary.add(new ContentRenderer(LivingStoryData.getSummary(), true, true));

        recentEvents.load();

        livingStoryService.getThemeInfoForLivingStory(LivingStoryData.getLivingStoryId(),
                new AsyncCallback<Map<Long, ContentItemTypesBundle>>() {
                    @Override
                    public void onFailure(Throwable caught) {
                    }

                    @Override
                    public void onSuccess(Map<Long, ContentItemTypesBundle> results) {
                        themeList.load(results);
                        filterList.load(results, themeList.getSelectedThemeId());
                    }
                });

        exportMethods();
    }

    /**
     * Sets off an asynchronous call that fills in data for the event list. In some circumstances,
     * can do its work synchronously.
     */
    public void update(FilterSpec filter, Long focusedContentItemId) {
        FilterSpec oldFilter = filterList.getFilter();
        if (!filter.equals(oldFilter)) {
            boolean simpleReversal = !contentItemList.hasMore() && filter.isReverseOf(oldFilter);
            filterList.setFilter(filter);
            if (simpleReversal) {
                contentItemList.doSimpleReversal(filter.oldestFirst);
            } else {
                contentService.getDisplayContentItemBundle(LivingStoryData.getLivingStoryId(), filter,
                        focusedContentItemId, null, new ContentItemCallback(focusedContentItemId));
                contentItemList.clear();
                contentItemList.beginLoading();
                beginLoading();
            }
        } else if (focusedContentItemId != null) {
            highlightEvent(focusedContentItemId, false);
        }
    }

    @Override
    public void changeState(String key, String value) {
        if (key.equals(SCROLL_POSITION_STATE)) {
            Window.scrollTo(0, Integer.valueOf(value));
            repositionAnchoredPanel();
        }
    }

    @Override
    public void onShow() {
        repositionAnchoredPanel();
    }

    @Override
    protected void onLoad() {
        super.onLoad();
        toggleEventHandler = EventBus.INSTANCE.addHandler(BlockToggledEvent.TYPE, new BlockToggledEvent.Handler() {
            @Override
            public void onToggle(BlockToggledEvent e) {
                if (e.isOpened() && e.shouldSetHistory()) {
                    // Set this content item as the focused contentitem in the history.
                    // When the user navigates away from this and then clicks back, this item will
                    // appear expanded, and the viewport will be scrolled to its position.
                    HistoryManager.newToken(HistoryPages.OVERVIEW,
                            LivingStoryControls.getCurrentFilterSpec().getFilterParams(),
                            String.valueOf(e.getContentItemId()));
                }
            }
        });
    }

    @Override
    public void onUnload() {
        super.onUnload();
        if (toggleEventHandler != null) {
            toggleEventHandler.removeHandler();
            toggleEventHandler = null;
        }
    }

    private class ContentItemCallback implements AsyncCallback<DisplayContentItemBundle> {
        private Long focusedContentItemId;

        public ContentItemCallback() {
            this(null);
        }

        public ContentItemCallback(Long focusedContentItemId) {
            this.focusedContentItemId = focusedContentItemId;
        }

        public void onFailure(Throwable t) {
            contentItemList.showError();
        }

        public void onSuccess(DisplayContentItemBundle bundle) {
            themeList.setSelectedThemeId(bundle.getAdjustedFilterSpec().themeId);
            if (!filterList.getFilter().equals(bundle.getAdjustedFilterSpec())) {
                filterList.setFilter(bundle.getAdjustedFilterSpec());
                contentItemList.clear();
            }
            contentItemList.finishLoading(bundle);
            if (focusedContentItemId != null) {
                contentItemList.goToContentItem(focusedContentItemId);
            }
            finishLoading();
            comments.loadCommentsBox("LSID:" + LivingStoryData.getLivingStoryId());
            rightPanel.setVisible(true);
        }
    }

    /**
     * "Jumps to" the event indicated by contentItemId, scrolling it into view and opening its
     * contents.
     * Only works for event and standalone narrative content items. 
     * Sets a history token when called.
     */
    public void highlightEvent(int contentItemId) {
        // Save the current scroll position in the history so that when the user clicks 'back',
        // they're scrolled back here.
        HistoryManager.changeState(SCROLL_POSITION_STATE, String.valueOf(Window.getScrollTop()));
        highlightEvent(contentItemId, true);
    }

    /**
     * Internal version of highlightEvent.  Lets the update() method above select an
     * event without setting an extra history token.
     */
    private void highlightEvent(long contentItemId, boolean setHistoryToken) {
        boolean finished = contentItemList.goToContentItem(contentItemId);
        if (!finished) {
            contentService.getDisplayContentItemBundle(LivingStoryData.getLivingStoryId(), filterList.getFilter(),
                    contentItemId, contentItemList.getNextDateInSequence(), new ContentItemCallback(contentItemId));
        }

        if (setHistoryToken) {
            // Set this content item as the focused item in the history.
            // When the user navigates away from this and then clicks back, this content item will
            // appear expanded, and the viewport will be scrolled to its position.
            HistoryManager.newToken(HistoryPages.OVERVIEW,
                    LivingStoryControls.getCurrentFilterSpec().getFilterParams(), String.valueOf(contentItemId));
        }
    }

    public void getMoreContentItems() {
        contentService.getDisplayContentItemBundle(LivingStoryData.getLivingStoryId(), filterList.getFilter(), null,
                contentItemList.getNextDateInSequence(), new ContentItemCallback());
        contentItemList.beginLoading();
    }

    public void repositionAnchoredPanel() {
        rightPanel.reposition();
    }

    public FilterSpec getCurrentFilterSpec() {
        return filterList.getFilter();
    }

    private native void exportMethods() /*-{
                                        var instance = this;
                                        $wnd.goToContentItem = function(contentItemId) {
                                        instance.@com.google.livingstories.client.lsp.views.OverviewPage::highlightEvent(I)
                                        .call(instance, contentItemId);
                                        }
                                        $wnd.repositionAnchoredPanel = function(contentItemId) {
                                        instance.@com.google.livingstories.client.lsp.views.OverviewPage::repositionAnchoredPanel()
                                        .call(instance);
                                        }
                                        $wnd.getMoreContentItems = function() {
                                        instance.@com.google.livingstories.client.lsp.views.OverviewPage::getMoreContentItems()
                                        .call(instance);
                                        }
                                        $wnd.getCurrentFilterSpec = function() {
                                        return instance.
                                        @com.google.livingstories.client.lsp.views.OverviewPage::getCurrentFilterSpec()
                                        .call(instance);
                                        }
                                        }-*/;
}