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 {
*/
protected boolean active;
/**
* Whether changes in status should be record.
*/
protected boolean trackStatus;
/**
* Whether user never received notifications from this chat.
*/
......@@ -109,6 +114,7 @@ public abstract class AbstractChat extends BaseEntity {
super(account, user);
threadId = StringUtils.randomString(12);
active = false;
trackStatus = false;
firstNotification = true;
lastText = "";
lastTime = null;
......@@ -264,6 +270,7 @@ public abstract class AbstractChat extends BaseEntity {
void openChat() {
active = true;
trackStatus = true;
}
void closeChat() {
......@@ -271,6 +278,10 @@ public abstract class AbstractChat extends BaseEntity {
firstNotification = true;
}
boolean isStatusTrackingEnabled() {
return trackStatus;
}
/**
* @return Target address for sending message.
*/
......@@ -390,7 +401,7 @@ public abstract class AbstractChat extends BaseEntity {
save = false;
Date timestamp = new Date();
if (notify || !incoming)
active = true;
openChat();
if (!incoming)
notify = false;
if (notify && !notifyAboutMessage())
......
......@@ -14,12 +14,9 @@
*/
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 com.xabber.android.data.account.StatusMode;
import com.xabber.androiddev.R;
/**
......@@ -180,20 +177,21 @@ public enum ChatAction {
*/
attention_requested;
public static ChatAction getChatAction(Presence presence) {
if (presence.getType() == Type.unavailable)
public static ChatAction getChatAction(StatusMode statusMode) {
if (statusMode == StatusMode.unavailable)
return ChatAction.unavailable;
Mode mode = presence.getMode();
if (mode == Mode.away)
else if (statusMode == StatusMode.available)
return ChatAction.available;
else if (statusMode == StatusMode.away)
return ChatAction.away;
else if (mode == Mode.chat)
else if (statusMode == StatusMode.chat)
return ChatAction.chat;
else if (mode == Mode.dnd)
else if (statusMode == StatusMode.dnd)
return ChatAction.dnd;
else if (mode == Mode.xa)
else if (statusMode == StatusMode.xa)
return ChatAction.xa;
else
return ChatAction.available;
throw new IllegalStateException();
}
/**
......
......@@ -43,6 +43,7 @@ import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.account.ArchiveMode;
import com.xabber.android.data.account.OnAccountArchiveModeChangedListener;
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.OnDisconnectListener;
import com.xabber.android.data.connection.OnPacketListener;
......@@ -50,6 +51,7 @@ import com.xabber.android.data.entity.BaseEntity;
import com.xabber.android.data.entity.NestedMap;
import com.xabber.android.data.extension.archive.MessageArchiveManager;
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.RosterManager;
import com.xabber.android.utils.StringUtils;
......@@ -67,7 +69,8 @@ import com.xabber.xmpp.delay.Delay;
*/
public class MessageManager implements OnLoadListener, OnPacketListener,
OnDisconnectListener, OnAccountRemovedListener,
OnRosterReceivedListener, OnAccountArchiveModeChangedListener {
OnRosterReceivedListener, OnAccountArchiveModeChangedListener,
OnStatusChangeListener {
/**
* Registered chats for bareAddresses in accounts.
......@@ -581,4 +584,28 @@ public class MessageManager implements OnLoadListener, OnPacketListener,
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;
import com.xabber.android.data.LogManager;
import com.xabber.android.data.NetworkException;
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.account.StatusMode;
import com.xabber.android.data.extension.archive.MessageArchiveManager;
import com.xabber.android.data.extension.otr.OTRManager;
import com.xabber.android.data.extension.otr.OTRUnencryptedException;
......@@ -50,21 +48,9 @@ public class RegularChat extends AbstractChat {
*/
private String resource;
/**
* Previous status text.
*/
private String statusText;
/**
* Previous status mode.
*/
private StatusMode statusMode;
RegularChat(String account, String user) {
super(account, user);
resource = null;
statusMode = null;
statusText = null;
}
public String getResource() {
......@@ -139,28 +125,6 @@ public class RegularChat extends AbstractChat {
&& presence.getType() == Presence.Type.unavailable
&& this.resource.equals(resource))
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) {
final Message message = (Message) packet;
if (message.getType() == Message.Type.error)
......
......@@ -53,19 +53,11 @@ public class AbstractContact extends BaseEntity {
}
public StatusMode getStatusMode() {
ResourceItem resourceItem = PresenceManager.getInstance()
.getResourceItem(account, user);
if (resourceItem == null)
return StatusMode.unavailable;
return resourceItem.getStatusMode();
return PresenceManager.getInstance().getStatusMode(account, user);
}
public String getStatusText() {
ResourceItem resourceItem = PresenceManager.getInstance()
.getResourceItem(account, user);
if (resourceItem == null)
return "";
return resourceItem.getStatusText();
return PresenceManager.getInstance().getStatusText(account, user);
}
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,
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
public void onPacket(ConnectionItem connection, String bareAddress,
Packet packet) {
......@@ -241,7 +255,10 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener,
resourceItem = null;
else
resourceItem = resourceContainer.get(resource);
StatusMode previousStatusMode = getStatusMode(account, bareAddress);
String previousStatusText = getStatusText(account, bareAddress);
if (presence.getType() == Type.available) {
StatusMode statusMode = StatusMode.createStatusMode(presence);
String statusText = presence.getStatus();
int priority = presence.getPriority();
if (statusText == null)
......@@ -255,13 +272,11 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener,
resourceContainer);
}
resourceContainer.put(resource, new ResourceItem(verbose,
StatusMode.createStatusMode(presence), statusText,
priority));
statusMode, statusText, priority));
resourceContainer.updateBest();
} else {
resourceItem.setVerbose(verbose);
resourceItem.setStatusMode(StatusMode
.createStatusMode(presence));
resourceItem.setStatusMode(statusMode);
resourceItem.setStatusText(statusText);
resourceItem.setPriority(priority);
resourceContainer.updateBest();
......@@ -276,6 +291,22 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener,
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()
.getRosterContact(account, bareAddress);
if (rosterContact != null) {
......@@ -286,6 +317,7 @@ public class PresenceManager implements OnArchiveModificationsReceivedListener,
OnRosterChangedListener.class))
listener.onPresenceChanged(rosterContacts);
}
RosterManager.getInstance().onContactChanged(account, bareAddress);
} else if (packet instanceof RosterPacket
&& ((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