Commit e510e180 authored by Alexander Ivanov's avatar Alexander Ivanov

Fix status tracking. Close #100.

parent 303dccc8
...@@ -73,6 +73,11 @@ public abstract class AbstractChat extends BaseEntity { ...@@ -73,6 +73,11 @@ public abstract class AbstractChat extends BaseEntity {
*/ */
protected boolean active; protected boolean active;
/**
* Whether changes in status should be record.
*/
protected boolean trackStatus;
/** /**
* Whether user never received notifications from this chat. * Whether user never received notifications from this chat.
*/ */
...@@ -109,6 +114,7 @@ public abstract class AbstractChat extends BaseEntity { ...@@ -109,6 +114,7 @@ public abstract class AbstractChat extends BaseEntity {
super(account, user); super(account, user);
threadId = StringUtils.randomString(12); threadId = StringUtils.randomString(12);
active = false; active = false;
trackStatus = false;
firstNotification = true; firstNotification = true;
lastText = ""; lastText = "";
lastTime = null; lastTime = null;
...@@ -264,6 +270,7 @@ public abstract class AbstractChat extends BaseEntity { ...@@ -264,6 +270,7 @@ public abstract class AbstractChat extends BaseEntity {
void openChat() { void openChat() {
active = true; active = true;
trackStatus = true;
} }
void closeChat() { void closeChat() {
...@@ -271,6 +278,10 @@ public abstract class AbstractChat extends BaseEntity { ...@@ -271,6 +278,10 @@ public abstract class AbstractChat extends BaseEntity {
firstNotification = true; firstNotification = true;
} }
boolean isStatusTrackingEnabled() {
return trackStatus;
}
/** /**
* @return Target address for sending message. * @return Target address for sending message.
*/ */
...@@ -390,7 +401,7 @@ public abstract class AbstractChat extends BaseEntity { ...@@ -390,7 +401,7 @@ public abstract class AbstractChat extends BaseEntity {
save = false; save = false;
Date timestamp = new Date(); Date timestamp = new Date();
if (notify || !incoming) if (notify || !incoming)
active = true; openChat();
if (!incoming) if (!incoming)
notify = false; notify = false;
if (notify && !notifyAboutMessage()) if (notify && !notifyAboutMessage())
......
...@@ -14,12 +14,9 @@ ...@@ -14,12 +14,9 @@
*/ */
package com.xabber.android.data.message; package com.xabber.android.data.message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Mode;
import org.jivesoftware.smack.packet.Presence.Type;
import android.content.Context; import android.content.Context;
import com.xabber.android.data.account.StatusMode;
import com.xabber.androiddev.R; import com.xabber.androiddev.R;
/** /**
...@@ -180,20 +177,21 @@ public enum ChatAction { ...@@ -180,20 +177,21 @@ public enum ChatAction {
*/ */
attention_requested; attention_requested;
public static ChatAction getChatAction(Presence presence) { public static ChatAction getChatAction(StatusMode statusMode) {
if (presence.getType() == Type.unavailable) if (statusMode == StatusMode.unavailable)
return ChatAction.unavailable; return ChatAction.unavailable;
Mode mode = presence.getMode(); else if (statusMode == StatusMode.available)
if (mode == Mode.away) return ChatAction.available;
else if (statusMode == StatusMode.away)
return ChatAction.away; return ChatAction.away;
else if (mode == Mode.chat) else if (statusMode == StatusMode.chat)
return ChatAction.chat; return ChatAction.chat;
else if (mode == Mode.dnd) else if (statusMode == StatusMode.dnd)
return ChatAction.dnd; return ChatAction.dnd;
else if (mode == Mode.xa) else if (statusMode == StatusMode.xa)
return ChatAction.xa; return ChatAction.xa;
else else
return ChatAction.available; throw new IllegalStateException();
} }
/** /**
......
...@@ -43,6 +43,7 @@ import com.xabber.android.data.account.AccountManager; ...@@ -43,6 +43,7 @@ import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.account.ArchiveMode; import com.xabber.android.data.account.ArchiveMode;
import com.xabber.android.data.account.OnAccountArchiveModeChangedListener; import com.xabber.android.data.account.OnAccountArchiveModeChangedListener;
import com.xabber.android.data.account.OnAccountRemovedListener; import com.xabber.android.data.account.OnAccountRemovedListener;
import com.xabber.android.data.account.StatusMode;
import com.xabber.android.data.connection.ConnectionItem; import com.xabber.android.data.connection.ConnectionItem;
import com.xabber.android.data.connection.OnDisconnectListener; import com.xabber.android.data.connection.OnDisconnectListener;
import com.xabber.android.data.connection.OnPacketListener; import com.xabber.android.data.connection.OnPacketListener;
...@@ -50,6 +51,7 @@ import com.xabber.android.data.entity.BaseEntity; ...@@ -50,6 +51,7 @@ import com.xabber.android.data.entity.BaseEntity;
import com.xabber.android.data.entity.NestedMap; import com.xabber.android.data.entity.NestedMap;
import com.xabber.android.data.extension.archive.MessageArchiveManager; import com.xabber.android.data.extension.archive.MessageArchiveManager;
import com.xabber.android.data.extension.muc.RoomChat; import com.xabber.android.data.extension.muc.RoomChat;
import com.xabber.android.data.roster.OnStatusChangeListener;
import com.xabber.android.data.roster.OnRosterReceivedListener; import com.xabber.android.data.roster.OnRosterReceivedListener;
import com.xabber.android.data.roster.RosterManager; import com.xabber.android.data.roster.RosterManager;
import com.xabber.android.utils.StringUtils; import com.xabber.android.utils.StringUtils;
...@@ -67,7 +69,8 @@ import com.xabber.xmpp.delay.Delay; ...@@ -67,7 +69,8 @@ import com.xabber.xmpp.delay.Delay;
*/ */
public class MessageManager implements OnLoadListener, OnPacketListener, public class MessageManager implements OnLoadListener, OnPacketListener,
OnDisconnectListener, OnAccountRemovedListener, OnDisconnectListener, OnAccountRemovedListener,
OnRosterReceivedListener, OnAccountArchiveModeChangedListener { OnRosterReceivedListener, OnAccountArchiveModeChangedListener,
OnStatusChangeListener {
/** /**
* Registered chats for bareAddresses in accounts. * Registered chats for bareAddresses in accounts.
...@@ -581,4 +584,28 @@ public class MessageManager implements OnLoadListener, OnPacketListener, ...@@ -581,4 +584,28 @@ public class MessageManager implements OnLoadListener, OnPacketListener,
return ids; return ids;
} }
private boolean isStatusTrackingEnabled(String account, String bareAddress) {
if (SettingsManager.chatsShowStatusChange() != ChatsShowStatusChange.always)
return false;
AbstractChat abstractChat = getChat(account, bareAddress);
return abstractChat != null && abstractChat instanceof RegularChat
&& abstractChat.isStatusTrackingEnabled();
}
@Override
public void onStatusChanged(String account, String bareAddress,
String resource, String statusText) {
if (isStatusTrackingEnabled(account, bareAddress))
getChat(account, bareAddress).newAction(resource, statusText,
ChatAction.status);
}
@Override
public void onStatusChanged(String account, String bareAddress,
String resource, StatusMode statusMode, String statusText) {
if (isStatusTrackingEnabled(account, bareAddress))
getChat(account, bareAddress).newAction(resource, statusText,
ChatAction.getChatAction(statusMode));
}
} }
...@@ -25,9 +25,7 @@ import org.jivesoftware.smackx.packet.MUCUser; ...@@ -25,9 +25,7 @@ import org.jivesoftware.smackx.packet.MUCUser;
import com.xabber.android.data.LogManager; import com.xabber.android.data.LogManager;
import com.xabber.android.data.NetworkException; import com.xabber.android.data.NetworkException;
import com.xabber.android.data.SettingsManager; import com.xabber.android.data.SettingsManager;
import com.xabber.android.data.SettingsManager.ChatsShowStatusChange;
import com.xabber.android.data.SettingsManager.SecurityOtrMode; import com.xabber.android.data.SettingsManager.SecurityOtrMode;
import com.xabber.android.data.account.StatusMode;
import com.xabber.android.data.extension.archive.MessageArchiveManager; import com.xabber.android.data.extension.archive.MessageArchiveManager;
import com.xabber.android.data.extension.otr.OTRManager; import com.xabber.android.data.extension.otr.OTRManager;
import com.xabber.android.data.extension.otr.OTRUnencryptedException; import com.xabber.android.data.extension.otr.OTRUnencryptedException;
...@@ -50,21 +48,9 @@ public class RegularChat extends AbstractChat { ...@@ -50,21 +48,9 @@ public class RegularChat extends AbstractChat {
*/ */
private String resource; private String resource;
/**
* Previous status text.
*/
private String statusText;
/**
* Previous status mode.
*/
private StatusMode statusMode;
RegularChat(String account, String user) { RegularChat(String account, String user) {
super(account, user); super(account, user);
resource = null; resource = null;
statusMode = null;
statusText = null;
} }
public String getResource() { public String getResource() {
...@@ -139,28 +125,6 @@ public class RegularChat extends AbstractChat { ...@@ -139,28 +125,6 @@ public class RegularChat extends AbstractChat {
&& presence.getType() == Presence.Type.unavailable && presence.getType() == Presence.Type.unavailable
&& this.resource.equals(resource)) && this.resource.equals(resource))
this.resource = null; this.resource = null;
if (presence.getType() == Presence.Type.error)
return true;
StatusMode mode = StatusMode.createStatusMode(presence);
String status = presence.getStatus();
ChatAction action;
boolean skip = statusText == null;
if (status == null)
status = "";
if (mode == statusMode && status.equals(statusText))
return true;
if (mode != statusMode) {
statusMode = mode;
action = ChatAction.getChatAction(presence);
} else {
action = ChatAction.status;
}
statusText = status;
if (skip || !active)
return true;
if (SettingsManager.chatsShowStatusChange() != ChatsShowStatusChange.always)
return true;
newAction(resource, status, action);
} else if (packet instanceof Message) { } else if (packet instanceof Message) {
final Message message = (Message) packet; final Message message = (Message) packet;
if (message.getType() == Message.Type.error) if (message.getType() == Message.Type.error)
......
...@@ -53,19 +53,11 @@ public class AbstractContact extends BaseEntity { ...@@ -53,19 +53,11 @@ public class AbstractContact extends BaseEntity {
} }
public StatusMode getStatusMode() { public StatusMode getStatusMode() {
ResourceItem resourceItem = PresenceManager.getInstance() return PresenceManager.getInstance().getStatusMode(account, user);
.getResourceItem(account, user);
if (resourceItem == null)
return StatusMode.unavailable;
return resourceItem.getStatusMode();
} }
public String getStatusText() { public String getStatusText() {
ResourceItem resourceItem = PresenceManager.getInstance() return PresenceManager.getInstance().getStatusText(account, user);
.getResourceItem(account, user);
if (resourceItem == null)
return "";
return resourceItem.getStatusText();
} }
public ClientSoftware getClientSoftware() { public ClientSoftware getClientSoftware() {
......
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License,
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.data.roster;
import com.xabber.android.data.BaseManagerInterface;
import com.xabber.android.data.account.StatusMode;
/**
* Listen for changes in presence.
*
* @author alexander.ivanov
*
*/
public interface OnStatusChangeListener extends BaseManagerInterface {
/**
* Notify when only status text changed.
*
* @param account
* @param bareAddress
* @param resource
* @param statusText
*/
void onStatusChanged(String account, String bareAddress, String resource,
String statusText);
/**
* Notify when status mode changed.
*
* @param account
* @param bareAddress
* @param resource
* @param statusMode
* @param statusText
*/
void onStatusChanged(String account, String bareAddress, String resource,
StatusMode statusMode, String statusText);
}
...@@ -207,6 +207,20 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener, ...@@ -207,6 +207,20 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener,
return container.getResourceItems(); return container.getResourceItems();
} }
public StatusMode getStatusMode(String account, String bareAddress) {
ResourceItem resourceItem = getResourceItem(account, bareAddress);
if (resourceItem == null)
return StatusMode.unavailable;
return resourceItem.getStatusMode();
}
public String getStatusText(String account, String bareAddress) {
ResourceItem resourceItem = getResourceItem(account, bareAddress);
if (resourceItem == null)
return "";
return resourceItem.getStatusText();
}
@Override @Override
public void onPacket(ConnectionItem connection, String bareAddress, public void onPacket(ConnectionItem connection, String bareAddress,
Packet packet) { Packet packet) {
...@@ -241,7 +255,10 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener, ...@@ -241,7 +255,10 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener,
resourceItem = null; resourceItem = null;
else else
resourceItem = resourceContainer.get(resource); resourceItem = resourceContainer.get(resource);
StatusMode previousStatusMode = getStatusMode(account, bareAddress);
String previousStatusText = getStatusText(account, bareAddress);
if (presence.getType() == Type.available) { if (presence.getType() == Type.available) {
StatusMode statusMode = StatusMode.createStatusMode(presence);
String statusText = presence.getStatus(); String statusText = presence.getStatus();
int priority = presence.getPriority(); int priority = presence.getPriority();
if (statusText == null) if (statusText == null)
...@@ -255,13 +272,11 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener, ...@@ -255,13 +272,11 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener,
resourceContainer); resourceContainer);
} }
resourceContainer.put(resource, new ResourceItem(verbose, resourceContainer.put(resource, new ResourceItem(verbose,
StatusMode.createStatusMode(presence), statusText, statusMode, statusText, priority));
priority));
resourceContainer.updateBest(); resourceContainer.updateBest();
} else { } else {
resourceItem.setVerbose(verbose); resourceItem.setVerbose(verbose);
resourceItem.setStatusMode(StatusMode resourceItem.setStatusMode(statusMode);
.createStatusMode(presence));
resourceItem.setStatusText(statusText); resourceItem.setStatusText(statusText);
resourceItem.setPriority(priority); resourceItem.setPriority(priority);
resourceContainer.updateBest(); resourceContainer.updateBest();
...@@ -276,6 +291,22 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener, ...@@ -276,6 +291,22 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener,
resourceContainer.updateBest(); resourceContainer.updateBest();
} }
} }
// Notify about changes
StatusMode newStatusMode = getStatusMode(account, bareAddress);
String newStatusText = getStatusText(account, bareAddress);
if (previousStatusMode != newStatusMode
|| !previousStatusText.equals(newStatusText))
for (OnStatusChangeListener listener : Application
.getInstance()
.getManagers(OnStatusChangeListener.class))
if (previousStatusMode == newStatusMode)
listener.onStatusChanged(account, bareAddress,
resource, newStatusText);
else
listener.onStatusChanged(account, bareAddress,
resource, newStatusMode, newStatusText);
RosterContact rosterContact = RosterManager.getInstance() RosterContact rosterContact = RosterManager.getInstance()
.getRosterContact(account, bareAddress); .getRosterContact(account, bareAddress);
if (rosterContact != null) { if (rosterContact != null) {
...@@ -286,6 +317,7 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener, ...@@ -286,6 +317,7 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener,
OnRosterChangedListener.class)) OnRosterChangedListener.class))
listener.onPresenceChanged(rosterContacts); listener.onPresenceChanged(rosterContacts);
} }
RosterManager.getInstance().onContactChanged(account, bareAddress); RosterManager.getInstance().onContactChanged(account, bareAddress);
} else if (packet instanceof RosterPacket } else if (packet instanceof RosterPacket
&& ((RosterPacket) packet).getType() != IQ.Type.ERROR) { && ((RosterPacket) packet).getType() != IQ.Type.ERROR) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment