/resources/ExDataset/codechanges/208/old/ChatController.java
Java | 2453 lines | 1777 code | 464 blank | 212 comment | 400 complexity | 0a10c9c7ee65359a08d3808dfeb153bc MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- package com.twofours.surespot.chat;
- import io.socket.IOAcknowledge;
- import io.socket.IOCallback;
- import io.socket.SocketIO;
- import io.socket.SocketIOException;
- import java.io.BufferedInputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InterruptedIOException;
- import java.io.PipedInputStream;
- import java.io.PipedOutputStream;
- import java.net.URI;
- import java.net.URISyntaxException;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map.Entry;
- import java.util.Timer;
- import java.util.TimerTask;
- import java.util.concurrent.ConcurrentLinkedQueue;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import android.app.Activity;
- import android.app.NotificationManager;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.graphics.Bitmap;
- import android.net.ConnectivityManager;
- import android.net.NetworkInfo;
- import android.os.AsyncTask;
- import android.os.Handler;
- import android.os.Looper;
- import android.support.v4.app.FragmentManager;
- import android.support.v4.view.ViewPager;
- import android.text.TextUtils;
- import ch.boye.httpclientandroidlib.Header;
- import ch.boye.httpclientandroidlib.HttpStatus;
- import ch.boye.httpclientandroidlib.HttpVersion;
- import ch.boye.httpclientandroidlib.StatusLine;
- import ch.boye.httpclientandroidlib.client.cache.HttpCacheEntry;
- import ch.boye.httpclientandroidlib.cookie.Cookie;
- import ch.boye.httpclientandroidlib.impl.client.cache.HeapResource;
- import ch.boye.httpclientandroidlib.impl.cookie.DateUtils;
- import ch.boye.httpclientandroidlib.message.BasicHeader;
- import ch.boye.httpclientandroidlib.message.BasicStatusLine;
- import com.actionbarsherlock.view.MenuItem;
- import com.loopj.android.http.AsyncHttpResponseHandler;
- import com.loopj.android.http.JsonHttpResponseHandler;
- import com.twofours.surespot.R;
- import com.twofours.surespot.StateController;
- import com.twofours.surespot.StateController.FriendState;
- import com.twofours.surespot.SurespotApplication;
- import com.twofours.surespot.activities.MainActivity;
- import com.twofours.surespot.common.SurespotConfiguration;
- import com.twofours.surespot.common.SurespotConstants;
- import com.twofours.surespot.common.SurespotLog;
- import com.twofours.surespot.common.Utils;
- import com.twofours.surespot.encryption.EncryptionController;
- import com.twofours.surespot.friends.AutoInviteData;
- import com.twofours.surespot.friends.Friend;
- import com.twofours.surespot.friends.FriendAdapter;
- import com.twofours.surespot.identity.IdentityController;
- import com.twofours.surespot.images.MessageImageDownloader;
- import com.twofours.surespot.network.IAsyncCallback;
- import com.twofours.surespot.network.IAsyncCallbackTuple;
- import com.twofours.surespot.network.NetworkController;
- import com.viewpagerindicator.TitlePageIndicator;
- public class ChatController {
- private static final String TAG = "ChatController";
- private static final int STATE_CONNECTING = 0;
- private static final int STATE_CONNECTED = 1;
- private static final int STATE_DISCONNECTED = 2;
- private static final int MAX_RETRIES = 16;
- private final StatusLine mImageStatusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "");
- private SocketIO socket;
- private int mRetries = 0;
- private Timer mBackgroundTimer;
- private IOCallback mSocketCallback;
- private ConcurrentLinkedQueue<SurespotMessage> mSendBuffer = new ConcurrentLinkedQueue<SurespotMessage>();
- private ConcurrentLinkedQueue<SurespotMessage> mResendBuffer = new ConcurrentLinkedQueue<SurespotMessage>();
- private int mConnectionState;
- private boolean mOnWifi;
- private NotificationManager mNotificationManager;
- private BroadcastReceiver mConnectivityReceiver;
- private HashMap<String, ChatAdapter> mChatAdapters;
- private HashMap<String, Integer> mEarliestMessage;
- private FriendAdapter mFriendAdapter;
- private ChatPagerAdapter mChatPagerAdapter;
- private ViewPager mViewPager;
- private TitlePageIndicator mIndicator;
- private FragmentManager mFragmentManager;
- private int mLatestUserControlId;
- private ArrayList<MenuItem> mMenuItems;
- private HashMap<String, LatestIdPair> mPreConnectIds;
- private static String mCurrentChat;
- private static boolean mPaused = true;
- private NetworkController mNetworkController;
- private Context mContext;
- public static final int MODE_NORMAL = 0;
- public static final int MODE_SELECT = 1;
- private int mMode = MODE_NORMAL;
- private IAsyncCallbackTuple<String, Boolean> mCallback401;
- private IAsyncCallback<Boolean> mProgressCallback;
- private IAsyncCallback<Void> mSendIntentCallback;
- private IAsyncCallback<Friend> mTabShowingCallback;
- private AutoInviteData mAutoInviteData;
- public ChatController(Context context, NetworkController networkController, FragmentManager fm, IAsyncCallbackTuple<String, Boolean> m401Handler,
- IAsyncCallback<Boolean> progressCallback, IAsyncCallback<Void> sendIntentCallback, IAsyncCallback<Friend> tabShowingCallback) {
- SurespotLog.v(TAG, "constructor: " + this);
- mContext = context;
- mNetworkController = networkController;
- mCallback401 = m401Handler;
- mProgressCallback = progressCallback;
- mSendIntentCallback = sendIntentCallback;
- mTabShowingCallback = tabShowingCallback;
- mEarliestMessage = new HashMap<String, Integer>();
- mChatAdapters = new HashMap<String, ChatAdapter>();
- mFriendAdapter = new FriendAdapter(mContext);
- mPreConnectIds = new HashMap<String, ChatController.LatestIdPair>();
- loadState();
- mFragmentManager = fm;
- mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
- setOnWifi();
- // mViewPager.setOffscreenPageLimit(2);
- mSocketCallback = new IOCallback() {
- @Override
- public void onMessage(JSONObject json, IOAcknowledge ack) {
- try {
- SurespotLog.v(TAG, "JSON Server said: %s", json.toString(2));
- }
- catch (JSONException e) {
- SurespotLog.w(TAG, "onMessage", e);
- }
- }
- @Override
- public void onMessage(String data, IOAcknowledge ack) {
- SurespotLog.v(TAG, "Server said: %s", data);
- }
- @Override
- public synchronized void onError(SocketIOException socketIOException) {
- // socket.io returns 403 for can't login
- if (socketIOException.getHttpStatus() == 403) {
- socket = null;
- logout();
- mCallback401.handleResponse(mContext.getString(R.string.could_not_login_to_server), false);
- return;
- }
- SurespotLog.i(TAG, socketIOException, "an Error occured, attempting reconnect with exponential backoff, retries: %d", mRetries);
- setOnWifi();
- // kick off another task
- if (mRetries < MAX_RETRIES) {
- if (mReconnectTask != null) {
- mReconnectTask.cancel();
- }
- int timerInterval = (int) (Math.pow(2, mRetries++) * 1000);
- SurespotLog.v(TAG, "Starting another task in: " + timerInterval);
- mReconnectTask = new ReconnectTask();
- if (mBackgroundTimer == null) {
- mBackgroundTimer = new Timer("backgroundTimer");
- }
- mBackgroundTimer.schedule(mReconnectTask, timerInterval);
- }
- else {
- // TODO tell user
- SurespotLog.i(TAG, "Socket.io reconnect retries exhausted, giving up.");
- mCallback401.handleResponse(mContext.getString(R.string.could_not_connect_to_server), true);
- }
- }
- @Override
- public void onDisconnect() {
- SurespotLog.v(TAG, "Connection terminated.");
- // socket = null;
- }
- @Override
- public void onConnect() {
- SurespotLog.v(TAG, "socket.io connection established");
- setState(STATE_CONNECTED);
- setOnWifi();
- mRetries = 0;
- if (mBackgroundTimer != null) {
- mBackgroundTimer.cancel();
- mBackgroundTimer = null;
- }
- if (mReconnectTask != null && mReconnectTask.cancel()) {
- SurespotLog.v(TAG, "Cancelled reconnect timer.");
- mReconnectTask = null;
- }
- connected();
- }
- @Override
- public void on(String event, IOAcknowledge ack, Object... args) {
- SurespotLog.v(TAG, "Server triggered event '" + event + "'");
- if (event.equals("control")) {
- try {
- SurespotControlMessage message = SurespotControlMessage.toSurespotControlMessage(new JSONObject((String) args[0]));
- handleControlMessage(null, message, true, false);
- }
- catch (JSONException e) {
- SurespotLog.w(TAG, "on control", e);
- }
- }
- else
- if (event.equals("message")) {
- try {
- JSONObject jsonMessage = new JSONObject((String) args[0]);
- SurespotLog.v(TAG, "received message: " + jsonMessage.toString());
- SurespotMessage message = SurespotMessage.toSurespotMessage(jsonMessage);
- handleMessage(message);
- checkAndSendNextMessage(message);
- // see if we have deletes
- String sDeleteControlMessages = jsonMessage.optString("deleteControlMessages", null);
- if (sDeleteControlMessages != null) {
- JSONArray deleteControlMessages = new JSONArray(sDeleteControlMessages);
- if (deleteControlMessages.length() > 0) {
- for (int i = 0; i < deleteControlMessages.length(); i++) {
- try {
- SurespotControlMessage dMessage = SurespotControlMessage.toSurespotControlMessage(new JSONObject(
- deleteControlMessages.getString(i)));
- handleControlMessage(null, dMessage, true, false);
- }
- catch (JSONException e) {
- SurespotLog.w(TAG, "on control", e);
- }
- }
- }
- }
- }
- catch (JSONException e) {
- SurespotLog.w(TAG, "on message", e);
- }
- }
- else
- if (event.equals("messageError")) {
- try {
- JSONObject jsonMessage = (JSONObject) args[0];
- SurespotLog.v(TAG, "received messageError: " + jsonMessage.toString());
- SurespotErrorMessage errorMessage = SurespotErrorMessage.toSurespotErrorMessage(jsonMessage);
- handleErrorMessage(errorMessage);
- }
- catch (JSONException e) {
- SurespotLog.w(TAG, "on messageError", e);
- }
- }
- }
- };
- mConnectivityReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- SurespotLog.v(TAG, "Connectivity Action");
- ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
- if (networkInfo != null) {
- SurespotLog.v(TAG, "isconnected: " + networkInfo.isConnected());
- SurespotLog.v(TAG, "failover: " + networkInfo.isFailover());
- SurespotLog.v(TAG, "reason: " + networkInfo.getReason());
- SurespotLog.v(TAG, "type: " + networkInfo.getTypeName());
- // if it's not a failover and wifi is now active then initiate reconnect
- if (!networkInfo.isFailover() && (networkInfo.getType() == ConnectivityManager.TYPE_WIFI && networkInfo.isConnected())) {
- synchronized (ChatController.this) {
- // if we're not connecting, connect
- if (getState() != STATE_CONNECTING && !mOnWifi) {
- SurespotLog.v(TAG, "Network switch, Reconnecting...");
- setState(STATE_CONNECTING);
- mOnWifi = true;
- disconnect();
- connect();
- }
- }
- }
- }
- else {
- SurespotLog.v(TAG, "networkinfo null");
- }
- }
- };
- }
- // this has to be done outside of the contructor as it creates fragments, which need chat controller instance
- public void init(ViewPager viewPager, TitlePageIndicator pageIndicator, ArrayList<MenuItem> menuItems, AutoInviteData autoInviteData) {
- mChatPagerAdapter = new ChatPagerAdapter(mContext, mFragmentManager);
- mMenuItems = menuItems;
- mAutoInviteData = autoInviteData;
- mViewPager = viewPager;
- mViewPager.setAdapter(mChatPagerAdapter);
- mIndicator = pageIndicator;
- mIndicator.setViewPager(mViewPager);
- mIndicator.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
- @Override
- public void onPageSelected(int position) {
- if (mChatPagerAdapter != null) {
- SurespotLog.v(TAG, "onPageSelected, position: " + position);
- String name = mChatPagerAdapter.getChatName(position);
- setCurrentChat(name);
- }
- }
- });
- mChatPagerAdapter.setChatNames(mFriendAdapter.getActiveChats());
- onResume();
- }
- private void connect() {
- SurespotLog.v(TAG, "connect, socket: " + socket + ", connected: " + (socket != null ? socket.isConnected() : false) + ", state: " + mConnectionState);
- // copy the latest ids so that we don't miss any if we receive new messages during the time we request messages and when the
- // connection completes (if they
- // are received out of order for some reason)
- //
- mPreConnectIds.clear();
- for (Entry<String, ChatAdapter> entry : mChatAdapters.entrySet()) {
- String username = entry.getKey();
- LatestIdPair idPair = new LatestIdPair();
- idPair.latestMessageId = getLatestMessageId(username);
- idPair.latestControlMessageId = getLatestMessageControlId(username);
- SurespotLog.v(TAG, "setting preconnectids for: " + username + ", latest message id: " + idPair.latestMessageId + ", latestcontrolid: "
- + idPair.latestControlMessageId);
- mPreConnectIds.put(username, idPair);
- }
- Cookie cookie = IdentityController.getCookie();
- if (cookie == null) {
- return;
- }
- try {
- HashMap<String, String> headers = new HashMap<String, String>();
- headers.put("cookie", cookie.getName() + "=" + cookie.getValue());
- socket = new SocketIO(SurespotConfiguration.getBaseUrl(), headers);
- socket.connect(mSocketCallback);
- }
- catch (Exception e) {
- SurespotLog.w(TAG, "connect", e);
- }
- }
- private void disconnect() {
- SurespotLog.v(TAG, "disconnect.");
- setState(STATE_DISCONNECTED);
- if (socket != null) {
- socket.disconnect();
- socket = null;
- }
- }
- private void connected() {
- getFriendsAndIds();
- resendMessages();
- // if we need to invite someone then do it
- if (mAutoInviteData != null) {
- if (mFriendAdapter.getFriend(mAutoInviteData.getUsername()) == null) {
- mNetworkController.invite(mAutoInviteData.getUsername(), mAutoInviteData.getSource(), new AsyncHttpResponseHandler() {
- @Override
- public void onSuccess(int statusCode, String arg0) {
- getFriendAdapter().addFriendInvited(mAutoInviteData.getUsername());
- mAutoInviteData = null;
- }
- });
- }
- else {
- Utils.makeToast(mContext, mContext.getString(R.string.autoinvite_user_exists, mAutoInviteData.getUsername()));
- mAutoInviteData = null;
- }
- }
- }
- private void resendMessages() {
- // get the resend messages
- SurespotMessage[] resendMessages = getResendMessages();
- JSONArray sMessageList = new JSONArray();
- for (int i = 0; i < resendMessages.length; i++) {
- SurespotMessage message = resendMessages[i];
- // if it has an id don't send it again
- if (message.getId() != null) {
- mResendBuffer.remove(message);
- continue;
- }
- // set the last received id so the server knows which messages to check
- String otherUser = message.getOtherUser();
- // String username = message.getFrom();
- Integer lastMessageID = 0;
- // ideally get the last id from the fragment's chat adapter
- ChatAdapter chatAdapter = mChatAdapters.get(otherUser);
- if (chatAdapter != null) {
- SurespotMessage lastMessage = chatAdapter.getLastMessageWithId();
- if (lastMessage != null) {
- lastMessageID = lastMessage.getId();
- }
- }
- // failing that use the last viewed id
- if (lastMessageID == null) {
- mFriendAdapter.getFriend(otherUser).getLastViewedMessageId();
- }
- SurespotLog.v(TAG, "setting resendId, otheruser: " + otherUser + ", id: " + lastMessageID);
- message.setResendId(lastMessageID);
- // String sMessage = message.toJSONObject().toString();
- sMessageList.put(message.toJSONObject());
- // enqueueMessage(message);
- // sendMessages();
- }
- socket.send(sMessageList.toString());
- }
- private void setOnWifi() {
- // get the initial state...sometimes when the app starts it says "hey i'm on wifi" which creates a reconnect
- ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
- if (networkInfo != null) {
- mOnWifi = (networkInfo.getType() == ConnectivityManager.TYPE_WIFI);
- }
- }
- private void checkAndSendNextMessage(SurespotMessage message) {
- sendMessages();
- if (mResendBuffer.size() > 0) {
- if (mResendBuffer.remove(message)) {
- SurespotLog.v(TAG, "Received and removed message from resend buffer: " + message);
- }
- }
- }
- private SurespotMessage[] getResendMessages() {
- SurespotMessage[] messages = mResendBuffer.toArray(new SurespotMessage[0]);
- // mResendBuffer.clear();
- return messages;
- }
- private void enqueueMessage(SurespotMessage message) {
- mSendBuffer.add(message);
- }
- private synchronized void sendMessages() {
- if (mBackgroundTimer == null) {
- mBackgroundTimer = new Timer("backgroundTimer");
- }
- SurespotLog.v(TAG, "Sending: " + mSendBuffer.size() + " messages.");
- Iterator<SurespotMessage> iterator = mSendBuffer.iterator();
- while (iterator.hasNext()) {
- SurespotMessage message = iterator.next();
- if (isMessageReadyToSend(message)) {
- iterator.remove();
- sendMessage(message);
- }
- else {
- break;
- }
- }
- }
- private boolean isMessageReadyToSend(SurespotMessage message) {
- return !TextUtils.isEmpty(message.getData()) && !TextUtils.isEmpty(message.getFromVersion()) && !TextUtils.isEmpty(message.getToVersion());
- }
- private void sendMessage(final SurespotMessage message) {
- SurespotLog.v(TAG, "sendmessage adding message to ResendBuffer, text: %s, iv: %s", message.getPlainData(), message.getIv());
- mResendBuffer.add(message);
- if (getState() == STATE_CONNECTED) {
- SurespotLog.v(TAG, "sendmessage, socket: %s", socket);
- JSONObject json = message.toJSONObject();
- SurespotLog.v(TAG, "sendmessage, json: %s", json);
- String s = json.toString();
- SurespotLog.v(TAG, "sendmessage, message string: %s", s);
- if (socket != null) {
- socket.send(s);
- }
- }
- }
- private int getState() {
- return mConnectionState;
- }
- private synchronized void setState(int state) {
- mConnectionState = state;
- }
- private ReconnectTask mReconnectTask;
- private class ReconnectTask extends TimerTask {
- @Override
- public void run() {
- SurespotLog.v(TAG, "Reconnect task run.");
- connect();
- }
- }
- private void handleMessage(final SurespotMessage message) {
- SurespotLog.v(TAG, "handleMessage %s", message);
- final String otherUser = message.getOtherUser();
- final ChatAdapter chatAdapter = mChatAdapters.get(otherUser);
- // if the adapter is open add the message
- if (chatAdapter != null) {
- // decrypt the message before adding it so the size is set properly
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- if (message.getMimeType().equals(SurespotConstants.MimeTypes.TEXT)) {
- // decrypt it before adding
- final String plainText = EncryptionController.symmetricDecrypt(message.getOurVersion(), message.getOtherUser(),
- message.getTheirVersion(), message.getIv(), message.getData());
- // substitute emoji
- if (plainText != null) {
- EmojiParser parser = EmojiParser.getInstance();
- message.setPlainData(parser.addEmojiSpans(plainText));
- }
- }
- else {
- if (message.getMimeType().equals(SurespotConstants.MimeTypes.IMAGE)) {
- // if it's an image that i sent
- // get the local message
- if (ChatUtils.isMyMessage(message)) {
- handleCachedFile(chatAdapter, message);
- }
- else {
- InputStream imageStream = MainActivity.getNetworkController().getFileStream(MainActivity.getContext(), message.getData());
- Bitmap bitmap = null;
- PipedOutputStream out = new PipedOutputStream();
- PipedInputStream inputStream;
- try {
- inputStream = new PipedInputStream(out);
- EncryptionController.runDecryptTask(message.getOurVersion(), message.getOtherUser(), message.getTheirVersion(),
- message.getIv(), new BufferedInputStream(imageStream), out);
- byte[] bytes = Utils.inputStreamToBytes(inputStream);
- bitmap = ChatUtils.getSampledImage(bytes);
- }
- catch (InterruptedIOException ioe) {
- SurespotLog.w(TAG, ioe, "handleMessage");
- }
- catch (IOException e) {
- SurespotLog.w(TAG, e, "handleMessage");
- }
- if (bitmap != null) {
- MessageImageDownloader.addBitmapToCache(message.getData(), bitmap);
- }
- }
- }
- else {
- if (message.getMimeType().equals(SurespotConstants.MimeTypes.M4A)) {
- if (ChatUtils.isMyMessage(message)) {
- handleCachedFile(chatAdapter, message);
- }
- else {
- InputStream encryptedVoiceStream = MainActivity.getNetworkController().getFileStream(MainActivity.getContext(),
- message.getData());
- PipedOutputStream out = new PipedOutputStream();
- PipedInputStream inputStream;
- try {
- inputStream = new PipedInputStream(out);
- EncryptionController.runDecryptTask(message.getOurVersion(), message.getOtherUser(), message.getTheirVersion(),
- message.getIv(), new BufferedInputStream(encryptedVoiceStream), out);
- byte[] bytes = Utils.inputStreamToBytes(inputStream);
- message.setPlainBinaryData(bytes);
- }
- catch (InterruptedIOException ioe) {
- SurespotLog.w(TAG, ioe, "handleMessage");
- }
- catch (IOException e) {
- SurespotLog.w(TAG, e, "handleMessage");
- }
- }
- }
- else {
- message.setPlainData("unknown message mime type");
- }
- }
- }
- return null;
- }
- protected void onPostExecute(Void result) {
- try {
- boolean added = applyControlMessages(chatAdapter, message, false, false, true);
- scrollToEnd(otherUser);
- Friend friend = mFriendAdapter.getFriend(otherUser);
- if (friend != null) {
- int messageId = message.getId();
- // always update the available id
- friend.setAvailableMessageId(messageId);
- // if the chat is showing set the last viewed id the id of the message we just received
- if (otherUser.equals(mCurrentChat)) {
- friend.setLastViewedMessageId(messageId);
- // if it was a voice message from the other user set play flag
- // TODO wrap in preference
- if (!ChatUtils.isMyMessage(message) && message.getMimeType().equals(SurespotConstants.MimeTypes.M4A)) {
- message.setPlayMedia(true);
- }
- }
- // chat not showing
- else {
- // if it's my message increment the count by one to account for it as I may have unread messages from the
- // other user; we
- // can't just set the last viewed to the latest message
- if (ChatUtils.isMyMessage(message) && added) {
- int adjustedLastViewedId = friend.getLastViewedMessageId() + 1;
- if (adjustedLastViewedId < messageId) {
- friend.setLastViewedMessageId(adjustedLastViewedId);
- }
- else {
- friend.setLastViewedMessageId(messageId);
- }
- }
- }
- mFriendAdapter.sort();
- mFriendAdapter.notifyDataSetChanged();
- }
- }
- catch (SurespotMessageSequenceException e) {
- SurespotLog.v(TAG, "handleMessage: %s", e.getMessage());
- getLatestMessagesAndControls(otherUser, e.getMessageId());
- }
- };
- }.execute();
- }
- else {
- Friend friend = mFriendAdapter.getFriend(otherUser);
- if (friend != null) {
- int messageId = message.getId();
- // always update the available id
- friend.setAvailableMessageId(messageId);
- mFriendAdapter.sort();
- mFriendAdapter.notifyDataSetChanged();
- }
- }
- }
- private boolean applyControlMessages(ChatAdapter chatAdapter, SurespotMessage message, boolean checkSequence, boolean sort, boolean notify) throws SurespotMessageSequenceException {
- // see if we have applicable control messages and apply them if necessary
- ArrayList<SurespotControlMessage> controlMessages = chatAdapter.getControlMessages();
- ArrayList<SurespotControlMessage> applicableControlMessages = new ArrayList<SurespotControlMessage>();
- for (SurespotControlMessage controlMessage : controlMessages) {
- int messageId = Integer.parseInt(controlMessage.getMoreData());
- if (message.getId() == messageId) {
- applicableControlMessages.add(controlMessage);
- }
- }
- boolean added = false;
- if (applicableControlMessages.size() == 0) {
- added = chatAdapter.addOrUpdateMessage(message, checkSequence, sort, notify);
- }
- else {
- added = chatAdapter.addOrUpdateMessage(message, checkSequence, false, false);
- for (SurespotControlMessage controlMessage : applicableControlMessages) {
- SurespotLog.v(TAG, "applying control message %s: to message %s", controlMessage, message);
- handleControlMessage(chatAdapter, controlMessage, false, true);
- }
- if (notify) {
- chatAdapter.notifyDataSetChanged();
- }
- }
- return added;
- }
- // add entry to http cache for image we sent so we don't download it again
- private void handleCachedFile(ChatAdapter chatAdapter, SurespotMessage message) {
- SurespotLog.v(TAG, "handleCachedFile");
- SurespotMessage localMessage = chatAdapter.getMessageByIv(message.getIv());
- // if the data is different we haven't updated the url to point externally
- if (localMessage != null && localMessage.getId() == null && !localMessage.getData().equals(message.getData())) {
- // add the remote cache entry for the new url
- String localUri = localMessage.getData();
- String remoteUri = message.getData();
- FileInputStream fis;
- try {
- fis = new FileInputStream(new File(new URI(localUri)));
- byte[] imageData = Utils.inputStreamToBytes(fis);
- HeapResource resource = new HeapResource(imageData);
- Date date = new Date();
- String sDate = DateUtils.formatDate(date);
- Header[] cacheHeaders = new Header[3];
- // create fake cache entry
- cacheHeaders[0] = new BasicHeader("Last-Modified", sDate);
- cacheHeaders[1] = new BasicHeader("Cache-Control", "public, max-age=31557600");
- cacheHeaders[2] = new BasicHeader("Date", sDate);
- HttpCacheEntry cacheEntry = new HttpCacheEntry(date, date, mImageStatusLine, cacheHeaders, resource);
- SurespotLog.v(TAG, "creating http cache entry for: %s", remoteUri);
- mNetworkController.addCacheEntry(remoteUri, cacheEntry);
- // update image cache
- if (message.getMimeType().equals(SurespotConstants.MimeTypes.IMAGE)) {
- MessageImageDownloader.copyAndRemoveCacheEntry(localUri, remoteUri);
- }
- }
- catch (FileNotFoundException e1) {
- SurespotLog.w(TAG, e1, "onMessage");
- }
- catch (URISyntaxException e1) {
- SurespotLog.w(TAG, e1, "onMessage");
- }
- catch (IOException e) {
- SurespotLog.w(TAG, e, "onMessage");
- }
- // delete the file
- try {
- SurespotLog.v(TAG, "handleCachedImage deleting local file: %s", localUri);
- File file = new File(new URI(localUri));
- file.delete();
- }
- catch (URISyntaxException e) {
- SurespotLog.w(TAG, e, "handleMessage");
- }
- // update message to point to real location
- localMessage.setData(remoteUri);
- }
- }
- // private void handleLocalData(ChatAdapter chatAdapter, SurespotMessage message) {
- // SurespotLog.v(TAG, "handleLocalData");
- // SurespotMessage localMessage = chatAdapter.getMessageByIv(message.getIv());
- //
- // // if the data is different we haven't updated the http cache with data we sent
- // if (localMessage != null && localMessage.getId() == null && !localMessage.getData().equals(message.getData()) && localMessage.getInlineData() != null) {
- // // add the remote cache entry for the new url
- //
- // byte[] imageData = localMessage.getInlineData();
- //
- // String remoteUri = message.getData();
- // HeapResource resource = new HeapResource(imageData);
- // Date date = new Date();
- // String sDate = DateUtils.formatDate(date);
- //
- // Header[] cacheHeaders = new Header[3];
- //
- // // create fake cache entry
- // cacheHeaders[0] = new BasicHeader("Last-Modified", sDate);
- // cacheHeaders[1] = new BasicHeader("Cache-Control", "public, max-age=31557600");
- // cacheHeaders[2] = new BasicHeader("Date", sDate);
- //
- // HttpCacheEntry cacheEntry = new HttpCacheEntry(date, date, mImageStatusLine, cacheHeaders, resource);
- //
- // SurespotLog.v(TAG, "creating http cache entry for: %s", remoteUri);
- // mNetworkController.addCacheEntry(remoteUri, cacheEntry);
- //
- // // update message to point to real location
- // localMessage.setData(remoteUri);
- //
- // // clear out the inline data as we should still have the decrypted plain data
- // localMessage.setInlineData(null);
- //
- // }
- // }
- // message handling shiznit
- void loadEarlierMessages(final String username, final IAsyncCallback<Boolean> callback) {
- // mLoading = true;
- // get the list of messages
- Integer firstMessageId = mEarliestMessage.get(username);
- if (firstMessageId == null) {
- firstMessageId = getEarliestMessageId(username);
- mEarliestMessage.put(username, firstMessageId);
- }
- // else {
- // firstMessageId -= 60;
- // if (firstMessageId < 1) {
- // firstMessageId = 1;
- // }
- // }
- if (firstMessageId != null) {
- if (firstMessageId > 1) {
- SurespotLog.v(TAG, username + ": asking server for messages before messageId: " + firstMessageId);
- // final int fMessageId = firstMessageId;
- final ChatAdapter chatAdapter = mChatAdapters.get(username);
- mNetworkController.getEarlierMessages(username, firstMessageId, new JsonHttpResponseHandler() {
- @Override
- public void onSuccess(final JSONArray jsonArray) {
- // if (getActivity() != null) {
- SurespotMessage message = null;
- try {
- for (int i = jsonArray.length() - 1; i >= 0; i--) {
- JSONObject jsonMessage = new JSONObject(jsonArray.getString(i));
- message = SurespotMessage.toSurespotMessage(jsonMessage);
- chatAdapter.insertMessage(message, false);
- }
- }
- catch (JSONException e) {
- SurespotLog.e(TAG, e, "%s: error creating chat message", username);
- }
- SurespotLog.v(TAG, "%s: loaded: %d earlier messages from the server.", username, jsonArray.length());
- if (message != null) {
- mEarliestMessage.put(username, message.getId());
- // chatAdapter.notifyDataSetChanged();
- }
- // chatAdapter.setLoading(false);
- callback.handleResponse(jsonArray.length() > 0);
- }
- @Override
- public void onFailure(Throwable error, String content) {
- SurespotLog.i(TAG, error, "%s: getEarlierMessages", username);
- // chatAdapter.setLoading(false);
- callback.handleResponse(false);
- }
- });
- }
- else {
- SurespotLog.v(TAG, "%s: getEarlierMessages: no more messages.", username);
- callback.handleResponse(false);
- // ChatFragment.this.mNoEarlierMessages = true;
- }
- }
- }
- private void getLatestIds() {
- SurespotLog.v(TAG, "getLatestIds");
- // setMessagesLoading(true);
- mNetworkController.getLatestIds(mLatestUserControlId, new JsonHttpResponseHandler() {
- @Override
- public void onSuccess(int statusCode, final JSONObject jsonResponse) {
- SurespotLog.v(TAG, "getlatestIds success, response: %s, statusCode: %d", jsonResponse, statusCode);
- JSONArray conversationIds = jsonResponse.optJSONArray("conversationIds");
- Friend friend = null;
- if (conversationIds != null) {
- for (int i = 0; i < conversationIds.length(); i++) {
- try {
- JSONObject jsonObject = conversationIds.getJSONObject(i);
- String spot = jsonObject.getString("conversation");
- Integer availableId = jsonObject.getInt("id");
- String user = ChatUtils.getOtherSpotUser(spot, IdentityController.getLoggedInUser());
- // update available ids
- friend = mFriendAdapter.getFriend(user);
- if (friend != null) {
- friend.setAvailableMessageId(availableId);
- }
- }
- catch (JSONException e) {
- SurespotLog.w(TAG, "getlatestIds", e);
- }
- }
- }
- JSONArray controlIds = jsonResponse.optJSONArray("controlIds");
- if (controlIds != null) {
- for (int i = 0; i < controlIds.length(); i++) {
- try {
- JSONObject jsonObject = controlIds.getJSONObject(i);
- String spot = jsonObject.getString("conversation");
- Integer availableId = jsonObject.getInt("id");
- String user = ChatUtils.getOtherSpotUser(spot, IdentityController.getLoggedInUser());
- // update available ids
- friend = mFriendAdapter.getFriend(user);
- if (friend != null) {
- friend.setAvailableMessageControlId(availableId);
- }
- }
- catch (JSONException e) {
- SurespotLog.w(TAG, "getlatestIds", e);
- }
- }
- }
- JSONArray userControlMessages = jsonResponse.optJSONArray("userControlMessages");
- if (userControlMessages != null) {
- handleControlMessages(IdentityController.getLoggedInUser(), userControlMessages);
- }
- if (friend != null) {
- mFriendAdapter.sort();
- mFriendAdapter.notifyDataSetChanged();
- }
- getLatestMessagesAndControls();
- }
- @Override
- public void onFailure(Throwable error, String content) {
- // setMessagesLoading(false);
- SurespotLog.i(TAG, error, "loading latest messages failed");
- Utils.makeToast(mContext, mContext.getString(R.string.loading_latest_messages_failed));
- setProgress(null, false);
- }
- });
- }
- private class LatestIdPair {
- public int latestMessageId;
- public int latestControlMessageId;
- }
- private void getLatestMessagesAndControls() {
- for (Entry<String, ChatAdapter> entry : mChatAdapters.entrySet()) {
- getLatestMessagesAndControls(entry.getKey());
- }
- // done with "global" updates
- setProgress(null, false);
- }
- private LatestIdPair getLatestIds(String username) {
- Friend friend = getFriendAdapter().getFriend(username);
- LatestIdPair idPair = mPreConnectIds.get(username);
- Integer latestMessageId = idPair.latestMessageId > -1 ? idPair.latestMessageId : 0;
- int latestAvailableId = friend.getAvailableMessageId();
- int latestControlId = idPair.latestControlMessageId > -1 ? idPair.latestControlMessageId : friend.getLastReceivedMessageControlId();
- int latestAvailableControlId = friend.getAvailableMessageControlId();
- int fetchMessageId = 0;
- if (latestMessageId > 0) {
- fetchMessageId = latestAvailableId > latestMessageId ? latestMessageId : -1;
- }
- int fetchControlMessageId = 0;
- if (latestControlId > 0) {
- fetchControlMessageId = latestAvailableControlId > latestControlId ? latestControlId : -1;
- }
- LatestIdPair intPair = new LatestIdPair();
- intPair.latestMessageId = fetchMessageId;
- intPair.latestControlMessageId = fetchControlMessageId;
- return intPair;
- }
- private void getLatestMessagesAndControls(final String username) {
- LatestIdPair ids = getLatestIds(username);
- getLatestMessagesAndControls(username, ids.latestMessageId, ids.latestControlMessageId);
- }
- private void getLatestMessagesAndControls(String username, int messageId) {
- getLatestMessagesAndControls(username, messageId, -1);
- }
- private void getLatestMessagesAndControls(final String username, int fetchMessageId, int fetchControlMessageId) {
- SurespotLog.v(TAG, "getLatestMessagesAndControls: name %s, fetchMessageId: %d, fetchControlMessageId: %d", username, fetchMessageId,
- fetchControlMessageId);
- if (fetchMessageId > -1 || fetchControlMessageId > -1) {
- setProgress(username, true);
- mNetworkController.getMessageData(username, fetchMessageId, fetchControlMessageId, new JsonHttpResponseHandler() {
- @Override
- public void onSuccess(int statusCode, JSONObject response) {
- JSONArray controlMessages = response.optJSONArray("controlMessages");
- String messages = response.optString("messages", null);
- if (messages != null) {
- handleMessages(username, messages);
- }
- if (controlMessages != null) {
- handleControlMessages(username, controlMessages);
- }
- setProgress(username, false);
- }
- });
- }
- }
- private void handleControlMessages(String username, JSONArray jsonArray) {
- SurespotLog.v(TAG, "%s: handleControlMessages", username);
- final ChatAdapter chatAdapter = mChatAdapters.get(username);
- SurespotControlMessage message = null;
- boolean messageActivity = false;
- boolean userActivity = false;
- for (int i = 0; i < jsonArray.length(); i++) {
- try {
- JSONObject jsonMessage = new JSONObject(jsonArray.getString(i));
- message = SurespotControlMessage.toSurespotControlMessage(jsonMessage);
- handleControlMessage(chatAdapter, message, false, false);
- // if it's a system message from another user then check version
- if (message.getType().equals("user")) {
- userActivity = true;
- }
- else
- if (message.getType().equals("message")) {
- messageActivity = true;
- }
- }
- catch (JSONException e) {
- SurespotLog.w(TAG, e, "%s: error creating chat message", username);
- }
- }
- if (message != null) {
- SurespotLog.v(TAG, "%s: loaded: %d latest control messages from the server.", username, jsonArray.length());
- if (messageActivity || userActivity) {
- Friend friend = mFriendAdapter.getFriend(username);
- if (friend != null) {
- if (messageActivity) {
- if (chatAdapter != null) {
- friend.setLastReceivedMessageControlId(message.getId());
- chatAdapter.sort();
- chatAdapter.notifyDataSetChanged();
- }
- friend.setAvailableMessageControlId(message.getId());
- mFriendAdapter.notifyDataSetChanged();
- }
- if (userActivity) {
- friend.setLastReceivedUserControlId(message.getId());
- saveFriends();
- mFriendAdapter.notifyDataSetChanged();
- }
- }
- }
- }
- // chatAdapter.setLoading(false);
- }
- private void handleControlMessage(ChatAdapter chatAdapter, SurespotControlMessage message, boolean notify, boolean reApplying) {
- // if it's a system message from another user then check version
- if (message.getType().equals("user")) {
- handleUserControlMessage(message, notify);
- }
- else
- if (message.getType().equals("message")) {
- String otherUser = ChatUtils.getOtherSpotUser(message.getData(), IdentityController.getLoggedInUser());
- Friend friend = mFriendAdapter.getFriend(otherUser);
- if (chatAdapter == null) {
- chatAdapter = mChatAdapters.get(otherUser);
- }
- if (chatAdapter != null) {
- // if we're not re applying this control message
- if (!reApplying) {
- // add control message to check messages against later for this session
- chatAdapter.addControlMessage(message);
- }
- boolean controlFromMe = message.getFrom().equals(IdentityController.getLoggedInUser());
- if (message.getAction().equals("delete")) {
- int messageId = Integer.parseInt(message.getMoreData());
- SurespotMessage dMessage = chatAdapter.getMessageById(messageId);
- if (dMessage != null) {
- deleteMessageInternal(chatAdapter, dMessage, controlFromMe);
- }
- }
- else {
- if (message.getAction().equals("deleteAll")) {
- if (message.getMoreData() != null) {
- if (controlFromMe) {
- chatAdapter.deleteAllMessages(Integer.parseInt(message.getMoreData()));
- }
- else {
- chatAdapter.deleteTheirMessages(Integer.parseInt(message.getMoreData()));
- }
- }
- }
- else {
- if (message.getAction().equals("shareable") || message.getAction().equals("notshareable")) {
- int messageId = Integer.parseInt(message.getMoreData());
- SurespotMessage dMessage = chatAdapter.getMessageById(messageId);
- if (dMessage != null) {
- SurespotLog.v(TAG, "setting message " + message.getAction());
- dMessage.setShareable(message.getAction().equals("shareable") ? true : false);
- }
- }
- }
- }
- }
- if (notify) {
- if (friend != null) {
- // if the chat adapter is open we will have acted upon the control message
- if (chatAdapter != null) {
- friend.setLastReceivedMessageControlId(message.getId());
- }
- friend.setAvailableMessageControlId(message.getId());
- }
- if (chatAdapter != null) {
- chatAdapter.notifyDataSetChanged();
- }
- }
- }
- }
- private void handleUserControlMessage(SurespotControlMessage message, boolean notify) {
- mLatestUserControlId = message.getId();
- String user = null;
- if (message.getAction().equals("revoke")) {
- IdentityController.updateLatestVersion(mContext, message.getData(), message.getMoreData());
- }
- else
- if (message.getAction().equals("invited")) {
- user = message.getData();
- mFriendAdapter.addFriendInvited(user);
- }
- else
- if (message.getAction().equals("added")) {
- user = message.getData();
- mFriendAdapter.addNewFriend(user);
- ChatAdapter chatAdapter = mChatAdapters.get(user);
- if (chatAdapter != null) {
- chatAdapter.userDeleted(false);
- }
- }
- else
- if (message.getAction().equals("invite")) {
- user = message.getData();
- mFriendAdapter.addFriendInviter(user);
- }
- else
- if (message.getAction().equals("ignore")) {
- String friendName = message.getData();
- Friend friend = mFriendAdapter.getFriend(friendName);
- // if they're not deleted, remove them
- if (friend != null) {
- if (!friend.isDeleted()) {
- mFriendAdapter.removeFriend(friendName);
- }
- else {
- // they've been deleted, just remove the invite flags
- friend.setInviter(false);
- friend.setInvited(false);
- }
- }
- }
- else
- if (message.getAction().equals("delete")) {
- String friendName = message.getData();
- Friend friend = mFriendAdapter.getFriend(friendName);
- if (friend != null) {
- // if it was just a delete of an invite
- if (friend.isInviter() || friend.isInvited()) {
- // if they're not deleted, remove them
- if (!friend.isDeleted()) {
- mFriendAdapter.removeFriend(friendName);
- }
- else {
- // they've been deleted, just remove the invite flags
- friend.setInviter(false);
- friend.setInvited(false);
- }
- // clear any associated invite notification
- String loggedInUser = IdentityController.getLoggedInUser();
- if (loggedInUser != null) {
- mNotificationManager.cancel(loggedInUser + ":" + friendName,
- SurespotConstants.IntentRequestCodes.INVITE_REQUEST_NOTIFICATION);
- }
- }
- // they really deleted us boo hoo
- else {
- handleDeleteUser(friendName, message.getMoreData(), notify);
- }
- }
- }
- if (notify) {
- Friend friend = mFriendAdapter.getFriend(user);
- if (friend != null) {
- friend.setLastReceivedUserControlId(message.getId());
- }
- mFriendAdapter.notifyDataSetChanged();
- saveFriends();
- }
- }
- private void handleDeleteUser(String deletedUser, String deleter, boolean notify) {
- SurespotLog.v(TAG, "handleDeleteUser, deletedUser: %s, deleter: %s", deletedUser, deleter);
- String username = IdentityController.getLoggedInUser();
- Friend friend = mFriendAdapter.getFriend(deletedUser);
- boolean iDidTheDeleting = deleter.equals(username);
- if (iDidTheDeleting) {
- // won't be needing this anymore
- closeTab(deletedUser);
- // blow all the state associated with this user away
- StateController.wipeUserState(mContext, username, deletedUser);
- // clear in memory cached data
- SurespotApplication.getCachingService().clearUserData(deletedUser);
- // clear the http cache
- mNetworkController.clearCache();
- // or you
- mFriendAdapter.removeFriend(deletedUser);
- }
- // you deleted me, you bastard!!
- else {
- ChatAdapter chatAdapter = mChatAdapters.get(deleter);
- // i'll delete all your messages then
- if (chatAdapter != null) {
- chatAdapter.userDeleted(true);
- if (notify) {
- chatAdapter.notifyDataSetChanged();
- }
- }
- // and mark you as deleted until I want to delete you
- friend.setDeleted();
- // force the controls to update
- if (friend != null && mCurrentChat != null && mCurrentChat.equals(deletedUser)) {
- mTabShowingCallback.handleResponse(friend);
- }
- }
- enableMenuItems(friend);
- }
- private void handleErrorMessage(SurespotErrorMessage errorMessage) {
- SurespotMessage message = null;
- Iterator<SurespotMessage> iterator = mResendBuffer.iterator();
- while (iterator.hasNext()) {
- message = iterator.next();
- if (message.getIv().equals(errorMessage.getId())) {
- iterator.remove();
- message.setErrorStatus(errorMessage.getStatus());
- break;
- }
- }
- if (message != null) {
- ChatAdapter chatAdapter = mChatAdapters.get(message.getOtherUser());
- if (chatAdapter != null) {
- chatAdapter.notifyDataSetChanged();
- }
- }
- }
- private void deleteMessageInternal(ChatAdapter chatAdapter, SurespotMessage dMessage, boolean initiatedByMe) {
- // if it's an image blow the http cache entry away
- if (dMessage.getMimeType() != null) {
- if (dMessage.getMimeType().equals(SurespotConstants.MimeTypes.IMAGE) || dMessage.getMimeType().equals(SurespotConstants.MimeTypes.M4A)) {
- mNetworkController.purgeCacheUrl(dMessage.getData());
- }
- boolean myMessage = dMessage.getFrom().equals(IdentityController.getLoggedInUser());
- // if i sent the delete, or it's not my message then delete it
- // (if someone else deleted my message we don't care)
- if (initiatedByMe || !myMessage) {
- SurespotLog.v(TAG, "deleting message");
- chatAdapter.deleteMessageById(dMessage.getId());
- }
- }
- }
- private void handleMessages(String username, String jsonMessageString) {
- SurespotLog.v(TAG, "%s: handleMessages", username);
- final ChatAdapter chatAdapter = mChatAdapters.get(username);
- if (chatAdapter == null) {
- return;
- }
- int sentByMeCount = 0;
- SurespotMessage lastMessage = null;
- try {
- JSONArray jsonUM = new JSONArray(jsonMessageString);
- SurespotLog.v(TAG, "%s: loaded: %d messages from the server: %s", username, jsonUM.length(), jsonMessageString);
- for (int i = 0; i < jsonUM.length(); i++) {
- lastMessage = SurespotMessage.toSurespotMessage(new JSONObject(jsonUM.getString(i)));
- boolean myMessage = lastMessage.getFrom().equals(IdentityController.getLoggedInUser());
- if (myMessage) {
- if (lastMessage.getMimeType().equals(SurespotConstants.MimeTypes.IMAGE)) {
- handleCachedFile(chatAdapter, lastMessage);
- }
- else {
- if (lastMessage.getMimeType().equals(SurespotConstants.MimeTypes.M4A)) {
- handleCachedFile(chatAdapter, lastMessage);
- }
- }
- }
- boolean added = applyControlMessages(chatAdapter, lastMessage, false, false, false);
- mResendBuffer.remove(lastMessage);
- if (added && myMessage) {
- sentByMeCount++;
- }
- }
- }
- catch (JSONException e) {
- SurespotLog.w(TAG, e, "jsonStringsToMessages");
- }
- catch (SurespotMessageSequenceException e) {
- // shouldn't happen
- SurespotLog.w(TAG, e, "handleMessages");
- // getLatestMessagesAndControls(username, e.getMessageId(), -1);
- // setProgress(username, false);
- return;
- }
- if (lastMessage != null) {
- Friend friend = mFriendAdapter.getFriend(username);
- int availableId = lastMessage.getId();
- friend.setAvailableMessageId(availableId);
- int lastViewedId = friend.getLastViewedMessageId();
- // how many new messages total are there
- int delta = availableId - lastViewedId;
- // if the current chat is showing or
- // all the new messages are mine then i've viewed them all
- if (username.equals(mCurrentChat) || sentByMeCount == delta) {
- friend.setLastViewedMessageId(availableId);
- }
- else {
- // set the last viewed id to the difference caused by their messages
- friend.setLastViewedMessageId(availableId - (delta - sentByMeCount));
- }
- chatAdapter.sort();
- chatAdapter.notifyDataSetChanged();
- chatAdapter.doneCheckingSequence();
- mFriendAdapter.sort();
- mFriendAdapter.notifyDataSetChanged();
- scrollToEnd(username);
- }
- // setProgress(username, false);
- }
- private Integer getEarliestMessageId(String username) {
- ChatAdapter chatAdapter = mChatAdapters.get(username);
- Integer firstMessageId = null;
- if (chatAdapter != null) {
- SurespotMessage firstMessage = chatAdapter.getFirstMessageWithId();
- if (firstMessage != null) {
- firstMessageId = firstMessage.getId();
- }
- }
- return firstMessageId;
- }
- private int getLatestMessageId(String username) {
- Integer lastMessageId = 0;
- ChatAdapter chatAdapter = mChatAdapters.get(username);
- if (chatAdapter != null) {
- SurespotMessage lastMessage = chatAdapter.getLastMessageWithId();
- if (lastMessage != null) {
- lastMessageId = lastMessage.getId();
- }
- }
- return lastMessageId;
- }
- private Integer getLatestMessageControlId(String username) {
- Friend friend = mFriendAdapter.getFriend(username);
- Integer lastControlId = null;
- if (friend != null) {
- lastControlId = friend.getLastReceivedMessageControlId();
- }
- return lastControlId == null ? 0 : lastControlId;
- }
- public synchronized void loadMessages(String username, boolean replace) {
- SurespotLog.v(TAG, "loadMessages: " + username);
- String loggedInUser = IdentityController.getLoggedInUser();
- if (!TextUtils.isEmpty(loggedInUser)) {
- String spot = ChatUtils.getSpot(loggedInUser, username);
- ChatAdapter chatAdapter = mChatAdapters.get(username);
- if (replace) {
- chatAdapter.setMessages(SurespotApplication.getStateController().loadMessages(spot));
- }
- else {
- chatAdapter.addOrUpdateMessages(S…
Large files files are truncated, but you can click here to view the full file