Commit 8035b4a7 authored by Yusuke Iwaki's avatar Yusuke Iwaki

add ativeUsers subscription ; add subscriptions/get logic.

parent e9ceb7f9
...@@ -11,7 +11,7 @@ import chat.rocket.android.fragment.chatroom.HomeFragment; ...@@ -11,7 +11,7 @@ import chat.rocket.android.fragment.chatroom.HomeFragment;
import chat.rocket.android.fragment.chatroom.RoomFragment; import chat.rocket.android.fragment.chatroom.RoomFragment;
import chat.rocket.android.helper.Avatar; import chat.rocket.android.helper.Avatar;
import chat.rocket.android.layouthelper.chatroom.RoomListManager; import chat.rocket.android.layouthelper.chatroom.RoomListManager;
import chat.rocket.android.model.Room; import chat.rocket.android.model.RoomSubscription;
import com.jakewharton.rxbinding.view.RxView; import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.widget.RxCompoundButton; import com.jakewharton.rxbinding.widget.RxCompoundButton;
import io.realm.Realm; import io.realm.Realm;
...@@ -75,12 +75,12 @@ public class MainActivity extends AbstractAuthedActivity { ...@@ -75,12 +75,12 @@ public class MainActivity extends AbstractAuthedActivity {
.subscribe(RxView.visibility(findViewById(R.id.user_action_container))); .subscribe(RxView.visibility(findViewById(R.id.user_action_container)));
} }
private RealmListObserver<Room> roomsObserver = new RealmListObserver<Room>() { private RealmListObserver<RoomSubscription> roomsObserver = new RealmListObserver<RoomSubscription>() {
@Override protected RealmResults<Room> queryItems(Realm realm) { @Override protected RealmResults<RoomSubscription> queryItems(Realm realm) {
return realm.where(Room.class).findAll(); return realm.where(RoomSubscription.class).findAll();
} }
@Override protected void onCollectionChanged(List<Room> list) { @Override protected void onCollectionChanged(List<RoomSubscription> list) {
roomListManager.setRooms(list); roomListManager.setRooms(list);
} }
}; };
......
...@@ -3,7 +3,7 @@ package chat.rocket.android.fragment.chatroom; ...@@ -3,7 +3,7 @@ package chat.rocket.android.fragment.chatroom;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import chat.rocket.android.R; import chat.rocket.android.R;
import chat.rocket.android.model.Room; import chat.rocket.android.model.RoomSubscription;
import io.realm.Realm; import io.realm.Realm;
import io.realm.RealmQuery; import io.realm.RealmQuery;
import jp.co.crowdworks.realm_java_helpers.RealmObjectObserver; import jp.co.crowdworks.realm_java_helpers.RealmObjectObserver;
...@@ -44,18 +44,18 @@ public class RoomFragment extends AbstractChatRoomFragment { ...@@ -44,18 +44,18 @@ public class RoomFragment extends AbstractChatRoomFragment {
} }
private RealmObjectObserver<Room> roomObserver = new RealmObjectObserver<Room>() { private RealmObjectObserver<RoomSubscription> roomObserver = new RealmObjectObserver<RoomSubscription>() {
@Override protected RealmQuery<Room> query(Realm realm) { @Override protected RealmQuery<RoomSubscription> query(Realm realm) {
return realm.where(Room.class).equalTo("_id", roomId); return realm.where(RoomSubscription.class).equalTo("rid", roomId);
} }
@Override protected void onChange(Room room) { @Override protected void onChange(RoomSubscription roomSubscription) {
onRenderRoom(room); onRenderRoom(roomSubscription);
} }
}; };
private void onRenderRoom(Room room) { private void onRenderRoom(RoomSubscription roomSubscription) {
activityToolbar.setTitle(room.getName()); activityToolbar.setTitle(roomSubscription.getName());
} }
@Override public void onResume() { @Override public void onResume() {
......
...@@ -4,7 +4,7 @@ import android.util.Patterns; ...@@ -4,7 +4,7 @@ import android.util.Patterns;
import bolts.Continuation; import bolts.Continuation;
import bolts.Task; import bolts.Task;
import chat.rocket.android.model.MethodCall; import chat.rocket.android.model.MethodCall;
import chat.rocket.android.model.Room; import chat.rocket.android.model.RoomSubscription;
import chat.rocket.android.model.ServerConfig; import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.ws.RocketChatWebSocketAPI; import chat.rocket.android.ws.RocketChatWebSocketAPI;
import java.util.UUID; import java.util.UUID;
...@@ -145,34 +145,83 @@ public class MethodCallHelper { ...@@ -145,34 +145,83 @@ public class MethodCallHelper {
} }
/** /**
* request "rooms/get". * request "subscriptions/get" and "rooms/get".
*/ */
public Task<Void> getRooms() { public Task<Void> getRooms() {
return call("rooms/get", param -> param.put("$date", 0), this::updateRooms); return getRoomSubscriptionRecursive(0)
.onSuccessTask(task -> getRoomRecursive(0))
.onSuccessTask(task -> Task.forResult(null));
} }
private Task<Void> updateRooms(Task<JSONObject> task) { private Task<Long> getRoomSubscriptionRecursive(long timestamp) {
JSONObject result = task.getResult(); return call("subscriptions/get", param -> param.put("$date", timestamp), task -> {
JSONObject result = task.getResult();
try { long nextTimestamp = 0;
JSONArray updatedRooms = result.getJSONArray("update"); try {
for (int i = 0; i < updatedRooms.length(); i++) { nextTimestamp = result.getJSONArray("remove")
updatedRooms.getJSONObject(i).put("serverConfigId", serverConfigId); .getJSONObject(0).getJSONObject("_deletedAt").getLong("$date");
} catch (JSONException exception) {
} }
return RealmHelperBolts.executeTransaction(realm -> { try {
realm.createOrUpdateAllFromJson(Room.class, result.getJSONArray("update")); JSONArray updatedRooms = result.getJSONArray("update");
JSONArray removedRooms = result.getJSONArray("remove"); for (int i = 0; i < updatedRooms.length(); i++) {
for (int i = 0; i < removedRooms.length(); i++) { updatedRooms.getJSONObject(i).put("serverConfigId", serverConfigId);
realm.where(Room.class)
.equalTo("serverConfigId", serverConfigId)
.equalTo("_id", removedRooms.getJSONObject(i).getString("_id"))
.findAll().deleteAllFromRealm();
} }
return null;
}); Task<Void> saveToDB = RealmHelperBolts.executeTransaction(realm -> {
} catch (JSONException exception) { realm.createOrUpdateAllFromJson(RoomSubscription.class, result.getJSONArray("update"));
return Task.forError(exception); return null;
} });
if (nextTimestamp > 0 && (timestamp == 0 || nextTimestamp < timestamp)) {
final long _next = nextTimestamp;
return saveToDB.onSuccessTask(_task -> getRoomSubscriptionRecursive(_next));
} else {
return saveToDB.onSuccessTask(_task -> Task.forResult(0L));
}
} catch (JSONException exception) {
return Task.forError(exception);
}
});
}
private Task<Long> getRoomRecursive(long timestamp) {
return call("rooms/get", param -> param.put("$date", timestamp), task -> {
JSONObject result = task.getResult();
long nextTimestamp = 0;
try {
nextTimestamp = result.getJSONArray("remove")
.getJSONObject(0).getJSONObject("_deletedAt").getLong("$date");
} catch (JSONException exception) {
}
try {
JSONArray updatedRooms = result.getJSONArray("update");
for (int i = 0; i < updatedRooms.length(); i++) {
JSONObject roomJson = updatedRooms.getJSONObject(i);
String rid = roomJson.getString("_id");
roomJson.put("rid", rid)
.put("serverConfigId", serverConfigId)
.remove("_id");
}
Task<Void> saveToDB = RealmHelperBolts.executeTransaction(realm -> {
realm.createOrUpdateAllFromJson(RoomSubscription.class, result.getJSONArray("update"));
return null;
});
if (nextTimestamp > 0 && (timestamp == 0 || nextTimestamp < timestamp)) {
final long _next = nextTimestamp;
return saveToDB.onSuccessTask(_task -> getRoomRecursive(_next));
} else {
return saveToDB.onSuccessTask(_task -> Task.forResult(0L));
}
} catch (JSONException exception) {
return Task.forError(exception);
}
});
} }
} }
...@@ -3,7 +3,7 @@ package chat.rocket.android.layouthelper.chatroom; ...@@ -3,7 +3,7 @@ package chat.rocket.android.layouthelper.chatroom;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import chat.rocket.android.helper.TextUtils; import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.model.Room; import chat.rocket.android.model.RoomSubscription;
import chat.rocket.android.widget.internal.RoomListItemView; import chat.rocket.android.widget.internal.RoomListItemView;
import java.util.List; import java.util.List;
...@@ -34,21 +34,21 @@ public class RoomListManager { ...@@ -34,21 +34,21 @@ public class RoomListManager {
/** /**
* update ViewGroups with room list. * update ViewGroups with room list.
*/ */
public void setRooms(List<Room> roomList) { public void setRooms(List<RoomSubscription> roomSubscriptionList) {
for (Room room : roomList) { for (RoomSubscription roomSubscription : roomSubscriptionList) {
String name = room.getName(); String name = roomSubscription.getName();
if (TextUtils.isEmpty(name)) { if (TextUtils.isEmpty(name)) {
continue; continue;
} }
String type = room.getT(); String type = roomSubscription.getT();
if (Room.TYPE_CHANNEL.equals(type) || Room.TYPE_PRIVATE.equals(type)) { if (RoomSubscription.TYPE_CHANNEL.equals(type) || RoomSubscription.TYPE_PRIVATE.equals(type)) {
insertOrUpdateItem(channelsContainer, room); insertOrUpdateItem(channelsContainer, roomSubscription);
removeItemIfExists(dmContainer, name); removeItemIfExists(dmContainer, name);
} else if (Room.TYPE_DIRECT_MESSAGE.equals(type)) { } else if (RoomSubscription.TYPE_DIRECT_MESSAGE.equals(type)) {
removeItemIfExists(channelsContainer, name); removeItemIfExists(channelsContainer, name);
insertOrUpdateItem(dmContainer, room); insertOrUpdateItem(dmContainer, roomSubscription);
} }
} }
} }
...@@ -60,15 +60,15 @@ public class RoomListManager { ...@@ -60,15 +60,15 @@ public class RoomListManager {
this.listener = listener; this.listener = listener;
} }
private void insertOrUpdateItem(ViewGroup parent, Room room) { private void insertOrUpdateItem(ViewGroup parent, RoomSubscription roomSubscription) {
final String roomName = room.getName(); final String roomName = roomSubscription.getName();
int index; int index;
for (index = 0; index < parent.getChildCount(); index++) { for (index = 0; index < parent.getChildCount(); index++) {
RoomListItemView roomListItemView = (RoomListItemView) parent.getChildAt(index); RoomListItemView roomListItemView = (RoomListItemView) parent.getChildAt(index);
final String targetRoomName = roomListItemView.getRoomName(); final String targetRoomName = roomListItemView.getRoomName();
if (roomName.equals(targetRoomName)) { if (roomName.equals(targetRoomName)) {
updateRoomItemView(roomListItemView, room); updateRoomItemView(roomListItemView, roomSubscription);
return; return;
} }
if (roomName.compareToIgnoreCase(targetRoomName) < 0) { if (roomName.compareToIgnoreCase(targetRoomName) < 0) {
...@@ -77,7 +77,7 @@ public class RoomListManager { ...@@ -77,7 +77,7 @@ public class RoomListManager {
} }
RoomListItemView roomListItemView = new RoomListItemView(parent.getContext()); RoomListItemView roomListItemView = new RoomListItemView(parent.getContext());
updateRoomItemView(roomListItemView, room); updateRoomItemView(roomListItemView, roomSubscription);
if (index == parent.getChildCount()) { if (index == parent.getChildCount()) {
parent.addView(roomListItemView); parent.addView(roomListItemView);
} else { } else {
...@@ -85,12 +85,12 @@ public class RoomListManager { ...@@ -85,12 +85,12 @@ public class RoomListManager {
} }
} }
private void updateRoomItemView(RoomListItemView roomListItemView, Room room) { private void updateRoomItemView(RoomListItemView roomListItemView, RoomSubscription roomSubscription) {
roomListItemView roomListItemView
.setRoomId(room.get_id()) .setRoomId(roomSubscription.getRid())
.setRoomName(room.getName()) .setRoomName(roomSubscription.getName())
.setRoomType(room.getT()) .setRoomType(roomSubscription.getT())
.setAlertCount(0); // TODO not implemented yet. .setUnreadCount(roomSubscription.getUnread());
roomListItemView.setOnClickListener(this::onItemClick); roomListItemView.setOnClickListener(this::onItemClick);
} }
......
package chat.rocket.android.model;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
/**
*/
public class Email extends RealmObject {
@PrimaryKey private String address;
private boolean verified;
}
...@@ -6,22 +6,23 @@ import io.realm.annotations.PrimaryKey; ...@@ -6,22 +6,23 @@ import io.realm.annotations.PrimaryKey;
/** /**
* subscription model for "meteor_accounts_loginServiceConfiguration". * subscription model for "meteor_accounts_loginServiceConfiguration".
*/ */
@SuppressWarnings("PMD.ShortVariable") @SuppressWarnings({"PMD.ShortClassName", "PMD.ShortVariable",
"PMD.MethodNamingConventions", "PMD.VariableNamingConventions"})
public class MeteorLoginServiceConfiguration public class MeteorLoginServiceConfiguration
extends RealmObject { extends RealmObject {
@PrimaryKey private String id; @PrimaryKey private String _id;
private String serverConfigId; private String serverConfigId;
private String service; private String service;
private String consumerKey; //for Twitter private String consumerKey; //for Twitter
private String appId; //for Facebook private String appId; //for Facebook
private String clientId; //for other auth providers private String clientId; //for other auth providers
public String getId() { public String get_id() {
return id; return _id;
} }
public void setId(String id) { public void set_id(String _id) {
this.id = id; this._id = _id;
} }
public String getServerConfigId() { public String getServerConfigId() {
......
...@@ -4,21 +4,24 @@ import io.realm.RealmObject; ...@@ -4,21 +4,24 @@ import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey; import io.realm.annotations.PrimaryKey;
/** /**
* Chat Room. * Chat Room(Subscription).
*/ */
@SuppressWarnings({"PMD.ShortClassName", "PMD.ShortVariable", @SuppressWarnings({"PMD.ShortClassName", "PMD.ShortVariable",
"PMD.MethodNamingConventions", "PMD.VariableNamingConventions"}) "PMD.MethodNamingConventions", "PMD.VariableNamingConventions"})
public class Room extends RealmObject { public class RoomSubscription extends RealmObject {
public static final String TYPE_CHANNEL = "c"; public static final String TYPE_CHANNEL = "c";
public static final String TYPE_PRIVATE = "p"; public static final String TYPE_PRIVATE = "p";
public static final String TYPE_DIRECT_MESSAGE = "d"; public static final String TYPE_DIRECT_MESSAGE = "d";
@PrimaryKey private String _id; private String _id; //subscriptionId
private String serverConfigId; private String serverConfigId;
@PrimaryKey private String rid; //roomId
private String name; private String name;
//private User u; // REMARK: do not save u, because it is just me.
private String t; //type { c: channel, d: direct message, p: private } private String t; //type { c: channel, d: direct message, p: private }
private User u; //User who created this room. private boolean open;
private String topic; private boolean alert;
private int unread;
public String get_id() { public String get_id() {
return _id; return _id;
...@@ -36,6 +39,14 @@ public class Room extends RealmObject { ...@@ -36,6 +39,14 @@ public class Room extends RealmObject {
this.serverConfigId = serverConfigId; this.serverConfigId = serverConfigId;
} }
public String getRid() {
return rid;
}
public void setRid(String rid) {
this.rid = rid;
}
public String getName() { public String getName() {
return name; return name;
} }
...@@ -52,19 +63,27 @@ public class Room extends RealmObject { ...@@ -52,19 +63,27 @@ public class Room extends RealmObject {
this.t = t; this.t = t;
} }
public User getU() { public boolean isOpen() {
return u; return open;
}
public void setOpen(boolean open) {
this.open = open;
}
public boolean isAlert() {
return alert;
} }
public void setU(User u) { public void setAlert(boolean alert) {
this.u = u; this.alert = alert;
} }
public String getTopic() { public int getUnread() {
return topic; return unread;
} }
public void setTopic(String topic) { public void setUnread(int unread) {
this.topic = topic; this.unread = unread;
} }
} }
package chat.rocket.android.model; package chat.rocket.android.model;
import io.realm.RealmList;
import io.realm.RealmObject; import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey; import io.realm.annotations.PrimaryKey;
...@@ -11,4 +12,47 @@ import io.realm.annotations.PrimaryKey; ...@@ -11,4 +12,47 @@ import io.realm.annotations.PrimaryKey;
public class User extends RealmObject { public class User extends RealmObject {
@PrimaryKey private String _id; @PrimaryKey private String _id;
private String username; private String username;
private String status;
private double utcOffset;
private RealmList<Email> emails;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public double getUtcOffset() {
return utcOffset;
}
public void setUtcOffset(double utcOffset) {
this.utcOffset = utcOffset;
}
public RealmList<Email> getEmails() {
return emails;
}
public void setEmails(RealmList<Email> emails) {
this.emails = emails;
}
} }
...@@ -9,6 +9,7 @@ import bolts.TaskCompletionSource; ...@@ -9,6 +9,7 @@ import bolts.TaskCompletionSource;
import chat.rocket.android.helper.LogcatIfError; import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.helper.TextUtils; import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.model.ServerConfig; import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.service.ddp_subscriber.ActiveUsersSubscriber;
import chat.rocket.android.service.ddp_subscriber.LoginServiceConfigurationSubscriber; import chat.rocket.android.service.ddp_subscriber.LoginServiceConfigurationSubscriber;
import chat.rocket.android.service.observer.MethodCallObserver; import chat.rocket.android.service.observer.MethodCallObserver;
import chat.rocket.android.service.observer.SessionObserver; import chat.rocket.android.service.observer.SessionObserver;
...@@ -30,6 +31,7 @@ import timber.log.Timber; ...@@ -30,6 +31,7 @@ import timber.log.Timber;
public class RocketChatWebSocketThread extends HandlerThread { public class RocketChatWebSocketThread extends HandlerThread {
private static final Class[] REGISTERABLE_CLASSES = { private static final Class[] REGISTERABLE_CLASSES = {
LoginServiceConfigurationSubscriber.class, LoginServiceConfigurationSubscriber.class,
ActiveUsersSubscriber.class,
TokenLoginObserver.class, TokenLoginObserver.class,
MethodCallObserver.class, MethodCallObserver.class,
SessionObserver.class SessionObserver.class
......
...@@ -92,7 +92,7 @@ abstract class AbstractDDPDocEventSubscriber implements Registerable { ...@@ -92,7 +92,7 @@ abstract class AbstractDDPDocEventSubscriber implements Registerable {
private void onDocumentAdded(Realm realm, DDPSubscription.Added docEvent) throws JSONException { private void onDocumentAdded(Realm realm, DDPSubscription.Added docEvent) throws JSONException {
//executed in RealmTransaction //executed in RealmTransaction
JSONObject json = new JSONObject().put("id", docEvent.docID); JSONObject json = new JSONObject().put("_id", docEvent.docID);
json.put("serverConfigId", serverConfigId); json.put("serverConfigId", serverConfigId);
mergeJson(json, docEvent.fields); mergeJson(json, docEvent.fields);
realm.createOrUpdateObjectFromJson(getModelClass(), customizeFieldJson(json)); realm.createOrUpdateObjectFromJson(getModelClass(), customizeFieldJson(json));
...@@ -108,7 +108,7 @@ abstract class AbstractDDPDocEventSubscriber implements Registerable { ...@@ -108,7 +108,7 @@ abstract class AbstractDDPDocEventSubscriber implements Registerable {
private void onDocumentChanged(Realm realm, DDPSubscription.Changed docEvent) private void onDocumentChanged(Realm realm, DDPSubscription.Changed docEvent)
throws JSONException { throws JSONException {
//executed in RealmTransaction //executed in RealmTransaction
JSONObject json = new JSONObject().put("id", docEvent.docID); JSONObject json = new JSONObject().put("_id", docEvent.docID);
json.put("serverConfigId", serverConfigId); json.put("serverConfigId", serverConfigId);
for (int i = 0; i < docEvent.cleared.length(); i++) { for (int i = 0; i < docEvent.cleared.length(); i++) {
String fieldToDelete = docEvent.cleared.getString(i); String fieldToDelete = docEvent.cleared.getString(i);
...@@ -128,7 +128,7 @@ abstract class AbstractDDPDocEventSubscriber implements Registerable { ...@@ -128,7 +128,7 @@ abstract class AbstractDDPDocEventSubscriber implements Registerable {
private void onDocumentRemoved(Realm realm, DDPSubscription.Removed docEvent) private void onDocumentRemoved(Realm realm, DDPSubscription.Removed docEvent)
throws JSONException { throws JSONException {
//executed in RealmTransaction //executed in RealmTransaction
realm.where(getModelClass()).equalTo("id", docEvent.docID).findAll().deleteAllFromRealm(); realm.where(getModelClass()).equalTo("_id", docEvent.docID).findAll().deleteAllFromRealm();
} }
private void mergeJson(JSONObject target, JSONObject src) throws JSONException { private void mergeJson(JSONObject target, JSONObject src) throws JSONException {
......
package chat.rocket.android.service.ddp_subscriber;
import android.content.Context;
import chat.rocket.android.model.User;
import chat.rocket.android.ws.RocketChatWebSocketAPI;
import io.realm.RealmObject;
/**
*/
public class ActiveUsersSubscriber extends AbstractDDPDocEventSubscriber {
public ActiveUsersSubscriber(Context context, String serverConfigId,
RocketChatWebSocketAPI api) {
super(context, serverConfigId, api);
}
@Override protected String getSubscriptionName() {
return "activeUsers";
}
@Override protected String getSubscriptionCallbackName() {
return "users";
}
@Override protected Class<? extends RealmObject> getModelClass() {
return User.class;
}
}
...@@ -52,7 +52,8 @@ public class SessionObserver extends AbstractModelObserver<ServerConfig> { ...@@ -52,7 +52,8 @@ public class SessionObserver extends AbstractModelObserver<ServerConfig> {
} }
@DebugLog private void onLogin() { @DebugLog private void onLogin() {
new MethodCallHelper(serverConfigId).getRooms() final MethodCallHelper methodCallHelper = new MethodCallHelper(serverConfigId);
methodCallHelper.getRooms()
.continueWith(new LogcatIfError()); .continueWith(new LogcatIfError());
} }
......
...@@ -77,7 +77,7 @@ public class RoomListItemView extends LinearLayout { ...@@ -77,7 +77,7 @@ public class RoomListItemView extends LinearLayout {
return this; return this;
} }
public RoomListItemView setAlertCount(int count) { public RoomListItemView setUnreadCount(int count) {
View alertCountContainer = findViewById(R.id.alert_count_container); View alertCountContainer = findViewById(R.id.alert_count_container);
TextView alertCount = (TextView) findViewById(R.id.alert_count); TextView alertCount = (TextView) findViewById(R.id.alert_count);
if (count > 0) { if (count > 0) {
......
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