cc.kune.chat.client.actions.ChatSitebarActions.java Source code

Java tutorial

Introduction

Here is the source code for cc.kune.chat.client.actions.ChatSitebarActions.java

Source

/*
 *
 * Copyright (C) 2007-2015 Licensed to the Comunes Association (CA) under
 * one or more contributor license agreements (see COPYRIGHT for details).
 * The CA licenses this file to you under the GNU Affero General Public
 * License version 3, (the "License"); you may not use this file except in
 * compliance with the License. This file is part of kune.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package cc.kune.chat.client.actions;

import org.waveprotocol.wave.client.events.ClientEvents;
import org.waveprotocol.wave.client.events.NetworkStatusEvent;
import org.waveprotocol.wave.client.events.NetworkStatusEventHandler;

import com.calclab.emite.core.client.events.StateChangedEvent;
import com.calclab.emite.core.client.events.StateChangedHandler;
import com.calclab.emite.core.client.xmpp.session.XmppSession;
import com.calclab.emite.core.client.xmpp.stanzas.Presence;
import com.calclab.emite.core.client.xmpp.stanzas.Presence.Show;
import com.calclab.emite.im.client.presence.PresenceManager;
import com.calclab.emite.im.client.presence.events.OwnPresenceChangedEvent;
import com.calclab.emite.im.client.presence.events.OwnPresenceChangedHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.Timer;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;

import br.com.rpa.client._paperelements.PaperButton;
import cc.kune.chat.client.ChatClient;
import cc.kune.chat.client.resources.ChatResources;
import cc.kune.common.client.actions.AbstractAction;
import cc.kune.common.client.actions.AbstractExtendedAction;
import cc.kune.common.client.actions.ActionEvent;
import cc.kune.common.client.actions.ui.descrip.MenuItemDescriptor;
import cc.kune.common.client.actions.ui.descrip.MenuRadioItemDescriptor;
import cc.kune.common.client.actions.ui.descrip.MenuSeparatorDescriptor;
import cc.kune.common.client.actions.ui.descrip.MenuTitleItemDescriptor;
import cc.kune.common.shared.i18n.I18nTranslationService;
import cc.kune.core.client.events.WindowFocusEvent;
import cc.kune.core.client.sitebar.SiteUserOptions;
import cc.kune.core.client.sitebar.SiteUserOptionsPresenter;
import cc.kune.core.shared.SessionConstants;

// TODO: Auto-generated Javadoc
/**
 * The Class ChatSitebarActions.
 *
 * @author vjrj@ourproject.org (Vicente J. Ruiz Jurado)
 */
public class ChatSitebarActions {

    /**
     * The Class ChangeOfflineStatusAction.
     *
     * @author vjrj@ourproject.org (Vicente J. Ruiz Jurado)
     */
    public class ChangeOfflineStatusAction extends AbstractExtendedAction {

        /** The session. */
        private final XmppSession session;

        /**
         * Instantiates a new change offline status action.
         *
         * @param session
         *          the session
         * @param icon
         *          the icon
         */
        public ChangeOfflineStatusAction(final XmppSession session) {
            this.session = session;
            session.addSessionStateChangedHandler(true, new StateChangedHandler() {
                @Override
                public void onStateChanged(final StateChangedEvent event) {
                    if (!session.isReady()) {
                        chatIcon.setIcon("kune:chat-status");
                        chatIcon.setStyleName(STYLE_PREFIX + "offline");
                    }
                }
            });
        }

        /*
         * (non-Javadoc)
         *
         * @see
         * cc.kune.common.client.actions.ActionListener#actionPerformed(cc.kune.
         * common.client.actions.ActionEvent)
         */
        @Override
        public void actionPerformed(final ActionEvent event) {
            session.logout();
        }
    }

    /**
     * The Class ChangeOnlineStatusAction.
     *
     * @author vjrj@ourproject.org (Vicente J. Ruiz Jurado)
     */
    public class ChangeOnlineStatusAction extends AbstractExtendedAction {

        /** The manager. */
        private final PresenceManager manager;

        /** The this presence. */
        private final Presence thisPresence;

        /**
         * Instantiates a new change online status action.
         *
         * @param presenceManager
         *          the presence manager
         * @param statusText
         *          the status text
         * @param show
         *          the show
         * @param icon
         *          the icon
         */
        public ChangeOnlineStatusAction(final PresenceManager presenceManager, final String statusText,
                final Show show) {
            this.manager = presenceManager;
            thisPresence = Presence.build(statusText, show);
            updateStatusIcon(presenceManager.getOwnPresence());
        }

        /*
         * (non-Javadoc)
         *
         * @see
         * cc.kune.common.client.actions.ActionListener#actionPerformed(cc.kune.
         * common.client.actions.ActionEvent)
         */
        @Override
        public void actionPerformed(final ActionEvent event) {
            if (!chatClient.loginIfNecessary()) {
                awayTimer.cancel();
                manager.changeOwnPresence(thisPresence);
            }
            nextPresence = thisPresence;
            chatClient.show();
        }

        /**
         * Update status icon.
         *
         * @param currentPresence
         *          the current presence
         */
        public void updateStatusIcon(final Presence currentPresence) {
            if (thisPresence.getShow().equals(currentPresence.getShow()) && ((currentPresence.getStatus() == null)
                    || currentPresence.getStatus().equals(thisPresence.getStatus()))) {
                setChatIcon(currentPresence.getShow());
            }
        }
    }

    /** The Constant AWAY_TIMER_MILLSECS. */
    private static final int AWAY_TIMER_MILLSECS = 60000;

    /** The Constant GROUP_CHAT_STATUS. */
    private static final String GROUP_CHAT_STATUS = "k-group-chat-status";

    /** The Constant NO_STATUS. */
    private static final String NO_STATUS = null;

    private static final String STYLE_PREFIX = "iron-icon-status-";

    /** The away item. */
    private MenuRadioItemDescriptor awayItem;

    /** The away timer. */
    private Timer awayTimer;

    /** The busy item. */
    private MenuRadioItemDescriptor busyItem;

    /** The chat client. */
    private final ChatClient chatClient;

    private final PaperButton chatIcon;

    /** The event bus. */
    private final EventBus eventBus;

    /** The i18n. */
    private final I18nTranslationService i18n;

    /** The next presence. */
    private Presence nextPresence = Presence.build(NO_STATUS, Show.notSpecified);

    /** The offline item. */
    private MenuRadioItemDescriptor offlineItem;

    /** The online item. */
    private MenuRadioItemDescriptor onlineItem;

    /** The presence manager. */
    private final PresenceManager presenceManager;

    /** The res. */
    private final ChatResources res;

    /** The user options. */
    private final SiteUserOptions userOptions;

    /** The xmpp session. */
    private final XmppSession xmppSession;

    /**
     * Instantiates a new chat sitebar actions.
     *
     * @param session
     *          the session
     * @param chatClient
     *          the chat client
     * @param userOptions
     *          the user options
     * @param i18n
     *          the i18n
     * @param res
     *          the res
     * @param xmppSession
     *          the xmpp session
     * @param presenceManager
     *          the presence manager
     * @param eventBus
     *          the event bus
     */
    @Inject
    public ChatSitebarActions(final SessionConstants session, final ChatClient chatClient,
            final SiteUserOptions userOptions, final I18nTranslationService i18n, final ChatResources res,
            final XmppSession xmppSession, final PresenceManager presenceManager, final EventBus eventBus) {
        chatIcon = (PaperButton) SiteUserOptionsPresenter.LOGGED_USER_MENU.getWidget();
        this.chatClient = chatClient;
        this.userOptions = userOptions;
        this.i18n = i18n;
        this.res = res;
        this.eventBus = eventBus;
        this.xmppSession = xmppSession;
        this.presenceManager = presenceManager;
        createActions();
        createListener();
    }

    /**
     * Creates the actions.
     */
    private void createActions() {
        final MenuSeparatorDescriptor separator = new MenuSeparatorDescriptor(
                SiteUserOptionsPresenter.LOGGED_USER_MENU);
        final MenuTitleItemDescriptor chatActionsTitle = new MenuTitleItemDescriptor(
                SiteUserOptionsPresenter.LOGGED_USER_MENU, i18n.t("Set your chat status"));
        // separator.setPosition(2);
        userOptions.addAction(separator);
        userOptions.addAction(chatActionsTitle);
        onlineItem = createChatStatusAction(res.online(), i18n.t("Available"),
                onlineAction(NO_STATUS, Show.notSpecified));
        awayItem = createChatStatusAction(res.away(), i18n.t("Away"), onlineAction(NO_STATUS, Show.away));
        busyItem = createChatStatusAction(res.busy(), i18n.t("Busy"), onlineAction(NO_STATUS, Show.dnd));
        offlineItem = createChatStatusAction(res.offline(), i18n.t("Sign out of chat"),
                new ChangeOfflineStatusAction(xmppSession));
    }

    /**
     * Creates the chat status action.
     *
     * @param icon
     *          the icon
     * @param text
     *          the text
     * @param action
     *          the action
     * @return the menu radio item descriptor
     */
    private MenuRadioItemDescriptor createChatStatusAction(final ImageResource icon, final String text,
            final AbstractAction action) {
        final MenuRadioItemDescriptor item = new MenuRadioItemDescriptor(SiteUserOptionsPresenter.LOGGED_USER_MENU,
                action, GROUP_CHAT_STATUS);
        item.putValue(AbstractAction.NAME, text);
        item.putValue(AbstractAction.SMALL_ICON, icon);
        return item;
    }

    /**
     * Creates the listener.
     */
    private void createListener() {
        awayTimer = new Timer() {
            @Override
            public void run() {
                final Presence awayPresence = Presence.build(NO_STATUS, Show.away);
                if (chatClient.isXmppLoggedIn()) {
                    presenceManager.changeOwnPresence(awayPresence);
                    updateMenuPresence(awayPresence);
                }
            }
        };
        xmppSession.addSessionStateChangedHandler(false, new StateChangedHandler() {
            @Override
            public void onStateChanged(final StateChangedEvent event) {
                if (xmppSession.isReady()) {
                    awayTimer.cancel();
                    presenceManager.changeOwnPresence(nextPresence);
                    updateMenuPresence(nextPresence);
                } else {
                    offlineItem.setChecked(true);
                }
            }
        });
        presenceManager.addOwnPresenceChangedHandler(new OwnPresenceChangedHandler() {
            @Override
            public void onOwnPresenceChanged(final OwnPresenceChangedEvent event) {
                updateMenuPresence(event.getCurrentPresence());
            }
        });
        eventBus.addHandler(WindowFocusEvent.getType(), new WindowFocusEvent.WindowFocusHandler() {
            @Override
            public void onWindowFocus(final WindowFocusEvent event) {
                if (event.isHasFocus()) {
                    awayTimer.cancel();
                    if (chatClient.isXmppLoggedIn()) {
                        new Timer() {
                            @Override
                            public void run() {
                                presenceManager.changeOwnPresence(nextPresence);
                            }
                        }.schedule(1000);
                    }
                } else {
                    awayTimer.schedule(AWAY_TIMER_MILLSECS);
                }
            }
        });
        ClientEvents.get().addNetworkStatusEventHandler(new NetworkStatusEventHandler() {
            @Override
            public void onNetworkStatus(final NetworkStatusEvent event) {
                switch (event.getStatus()) {
                case CONNECTED:
                case RECONNECTED:
                    new Timer() {
                        @Override
                        public void run() {
                            ChatSitebarActions.this.chatClient.loginIfNecessary();
                        }
                    }.schedule(2000);
                    break;
                default:
                case DISCONNECTED:
                case RECONNECTING:
                    break;
                }
            }
        });
    }

    /**
     * Online action.
     *
     * @param statusText
     *          the status text
     * @param show
     *          the show
     * @param icon
     *          the icon
     * @return the abstract extended action
     */
    private AbstractExtendedAction onlineAction(final String statusText, final Show show) {
        return new ChangeOnlineStatusAction(presenceManager, statusText, show);
    }

    private void setChatIcon(final Show show) {
        switch (show) {
        case notSpecified:
            chatIcon.setIcon("kune:chat-status");
            chatIcon.setStyleName(STYLE_PREFIX + "online");
            break;
        case dnd:
            chatIcon.setIcon("kune:chat-status");
            chatIcon.setStyleName(STYLE_PREFIX + "busy");
            break;
        case chat:
            chatIcon.setIcon("kune:chat-status");
            chatIcon.setStyleName(STYLE_PREFIX + "online");
            break;
        default:
        case away:
            chatIcon.setIcon("kune:chat-status-away");
            chatIcon.setStyleName(STYLE_PREFIX + "away");
            break;
        }
    }

    /**
     * Update menu presence.
     *
     * @param presence
     *          the presence
     */
    private void updateMenuPresence(final Presence presence) {
        switch (presence.getShow()) {
        case notSpecified:
            onlineItem.setChecked(true);
            updateSitebarIconPresence(presence, onlineItem);
            break;
        case dnd:
            busyItem.setChecked(true);
            updateSitebarIconPresence(presence, busyItem);
            break;
        case chat:
            onlineItem.setChecked(true);
            updateSitebarIconPresence(presence, onlineItem);
            break;
        default:
        case away:
            awayItem.setChecked(true);
            updateSitebarIconPresence(presence, awayItem);
            break;
        }
    }

    /**
     * Update sitebar icon presence.
     *
     * @param presence
     *          the presence
     * @param itemDescriptor
     *          the item descriptor
     */
    private void updateSitebarIconPresence(final Presence presence, final MenuItemDescriptor itemDescriptor) {
        ((ChatSitebarActions.ChangeOnlineStatusAction) itemDescriptor.getAction()).updateStatusIcon(presence);
    }
}