/* * * 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); } }