package com.zulip.android.networking;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import com.zulip.android.ZulipApp;
import com.zulip.android.activities.ZulipActivity;
import com.zulip.android.models.Presence;
import com.zulip.android.models.PresenceType;
import com.zulip.android.util.ZLog;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Iterator;
import java.util.Map;
/**
* Sends a status update and fetches updates for other users.
*/
public class AsyncStatusUpdate extends ZulipAsyncPushTask {
private static final String STATUS = "status";
private static final String TIMESTAMP = "timestamp";
private static final String STATUS_UPDATE = "statusUpdate";
private final Context context;
/**
* Declares a new HumbugAsyncPushTask, passing the activity as context.
*
* @param activity {@link android.app.Activity}
*/
public AsyncStatusUpdate(ZulipActivity activity) {
super((ZulipApp) activity.getApplication());
this.context = activity;
setProperty(STATUS, "active");
}
public final void execute() {
execute("POST", "v1/users/me/presence");
}
/**
* Choose presence object. This will return the latest active presence, then
* the latest away presence available.
*/
private JSONObject chooseLatestPresence(JSONObject person)
throws JSONException {
Iterator keys = person.keys();
JSONObject latestPresence = null;
while (keys.hasNext()) {
String key = (String) keys.next();
JSONObject presence = person.getJSONObject(key);
long timestamp = presence.getLong(TIMESTAMP);
String status = presence.getString(STATUS);
if (latestPresence == null) {
// first presence
latestPresence = presence;
} else {
String latestStatus = latestPresence.getString(STATUS);
if (latestStatus == null) {
Log.wtf(STATUS_UPDATE,
"Received presence information with no status");
} else if (status == null) {
Log.wtf(STATUS_UPDATE,
"Received presence information with no status");
} else {
if (status.equals(PresenceType.ACTIVE.toString())) {
if (latestStatus.equals(PresenceType.ACTIVE.toString())) {
if (latestPresence.getLong(TIMESTAMP) < timestamp) {
latestPresence = presence;
}
} else {
// found an active status which overrides the idle
// status
latestPresence = presence;
}
} else if (status.equals(PresenceType.IDLE.toString())
&& latestStatus.equals(PresenceType.IDLE.toString())
&& latestPresence.getLong(TIMESTAMP) < timestamp) {
latestPresence = presence;
}
}
}
}
return latestPresence;
}
@Override
protected void onPostExecute(String result) {
if (result != null) {
try {
JSONObject obj = new JSONObject(result);
if (obj.getString("result").equals("success")) {
Map<String, Presence> presenceLookup = this.app.presences;
presenceLookup.clear();
JSONObject presences = obj.getJSONObject("presences");
long serverTimestamp = (long) obj
.getDouble("server_timestamp");
if (presences != null) {
Iterator emailIterator = presences.keys();
while (emailIterator.hasNext()) {
String email = (String) emailIterator.next();
JSONObject person = presences.getJSONObject(email);
// iterate through the devices providing updates and
// use the status of the latest one
JSONObject latestPresenceObj = chooseLatestPresence(person);
if (latestPresenceObj != null) {
long age = serverTimestamp
- latestPresenceObj
.getLong(TIMESTAMP);
String status = latestPresenceObj
.getString(STATUS);
String client = latestPresenceObj
.getString("client");
PresenceType statusEnum;
if (status == null) {
statusEnum = null;
} else if (status.equals(PresenceType.ACTIVE
.toString())) {
statusEnum = PresenceType.ACTIVE;
} else if (status.equals(PresenceType.IDLE
.toString())) {
statusEnum = PresenceType.IDLE;
} else {
statusEnum = null;
}
Presence presence = new Presence(age, client,
statusEnum);
presenceLookup.put(email, presence);
}
}
}
callback.onTaskComplete(result, obj);
return;
}
} catch (JSONException e) {
ZLog.logException(e);
}
}
Toast.makeText(context, "Unknown error", Toast.LENGTH_LONG).show();
Log.wtf(STATUS_UPDATE,
"An exception was thrown or we got a failed response from the server for status updates.");
}
}