Commit 9dab2bf7 authored by Rafael Kellermann Streit's avatar Rafael Kellermann Streit Committed by GitHub

Merge branch 'develop' into iss321

parents e38ca8d4 388a4f9c
package chat.rocket.android_ddp; package chat.rocket.android_ddp;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import io.reactivex.Flowable;
import org.json.JSONArray; import org.json.JSONArray;
import bolts.Task; import bolts.Task;
import bolts.TaskCompletionSource; import bolts.TaskCompletionSource;
import chat.rocket.android_ddp.rx.RxWebSocketCallback; import chat.rocket.android_ddp.rx.RxWebSocketCallback;
import io.reactivex.Flowable;
import io.reactivex.Maybe;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
public class DDPClient { public class DDPClient {
...@@ -34,6 +36,10 @@ public class DDPClient { ...@@ -34,6 +36,10 @@ public class DDPClient {
return task.getTask(); return task.getTask();
} }
public Maybe<DDPClientCallback.Base> doPing(@Nullable String id) {
return impl.ping(id);
}
public Task<DDPClientCallback.RPC> rpc(String method, JSONArray params, String id, public Task<DDPClientCallback.RPC> rpc(String method, JSONArray params, String id,
long timeoutMs) { long timeoutMs) {
TaskCompletionSource<DDPClientCallback.RPC> task = new TaskCompletionSource<>(); TaskCompletionSource<DDPClientCallback.RPC> task = new TaskCompletionSource<>();
......
package chat.rocket.android_ddp; package chat.rocket.android_ddp;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -53,6 +54,15 @@ public class DDPClientCallback { ...@@ -53,6 +54,15 @@ public class DDPClientCallback {
this.id = id; this.id = id;
} }
public static class UnMatched extends Base {
@NonNull public String id;
public UnMatched(DDPClient client, @NonNull String id) {
super(client);
this.id = id;
}
}
public static class Timeout extends BaseException { public static class Timeout extends BaseException {
public Timeout(DDPClient client) { public Timeout(DDPClient client) {
super(Timeout.class, client); super(Timeout.class, client);
......
...@@ -17,6 +17,7 @@ import chat.rocket.android.log.RCLog; ...@@ -17,6 +17,7 @@ import chat.rocket.android.log.RCLog;
import chat.rocket.android_ddp.rx.RxWebSocket; import chat.rocket.android_ddp.rx.RxWebSocket;
import chat.rocket.android_ddp.rx.RxWebSocketCallback; import chat.rocket.android_ddp.rx.RxWebSocketCallback;
import io.reactivex.Flowable; import io.reactivex.Flowable;
import io.reactivex.Maybe;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
...@@ -106,6 +107,43 @@ public class DDPClientImpl { ...@@ -106,6 +107,43 @@ public class DDPClientImpl {
} }
} }
public Maybe<DDPClientCallback.Base> ping(@Nullable final String id) {
final boolean requested = (TextUtils.isEmpty(id)) ?
sendMessage("ping", null) :
sendMessage("ping", json -> json.put("id", id));
if (requested) {
return flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson)
.filter(response -> "pong".equalsIgnoreCase(extractMsg(response)))
.doOnError(error -> {
RCLog.e(error, "Heartbeat ping[%s] xxx failed xxx", id);
})
.map(response -> {
String msg = extractMsg(response);
if ("pong".equals(msg)) {
RCLog.d("pong[%s] <", id);
if (response.isNull("id")) {
return new DDPClientCallback.Ping(client, null);
} else {
String _id = response.optString("id");
if (id.equals(_id)) {
return new DDPClientCallback.Ping(client, _id);
} else {
return new DDPClientCallback.Ping.UnMatched(client, _id);
}
}
}
// if we receive anything other than a pong throw an exception
throw new DDPClientCallback.RPC.Error(client, id, response);
}).firstElement();
} else {
return Maybe.error(new DDPClientCallback.Closed(client));
}
}
public void ping(final TaskCompletionSource<DDPClientCallback.Ping> task, public void ping(final TaskCompletionSource<DDPClientCallback.Ping> task,
@Nullable final String id) { @Nullable final String id) {
...@@ -127,12 +165,10 @@ public class DDPClientImpl { ...@@ -127,12 +165,10 @@ public class DDPClientImpl {
if ("pong".equals(msg)) { if ("pong".equals(msg)) {
if (response.isNull("id")) { if (response.isNull("id")) {
task.setResult(new DDPClientCallback.Ping(client, null)); task.setResult(new DDPClientCallback.Ping(client, null));
disposables.clear();
} else { } else {
String _id = response.optString("id"); String _id = response.optString("id");
if (id.equals(_id)) { if (id.equals(_id)) {
task.setResult(new DDPClientCallback.Ping(client, id)); task.setResult(new DDPClientCallback.Ping(client, id));
disposables.clear();
} }
} }
disposables.clear(); disposables.clear();
...@@ -368,12 +404,11 @@ public class DDPClientImpl { ...@@ -368,12 +404,11 @@ public class DDPClientImpl {
try { try {
JSONObject origJson = new JSONObject().put("msg", msg); JSONObject origJson = new JSONObject().put("msg", msg);
String msg2 = (json == null ? origJson : json.create(origJson)).toString(); String msg2 = (json == null ? origJson : json.create(origJson)).toString();
websocket.sendText(msg2); return websocket.sendText(msg2);
} catch (Exception e) { } catch (Exception e) {
RCLog.e(e); RCLog.e(e);
return false; return false;
} }
return true; // ignore exception here.
} }
private void sendMessage(String msg, @Nullable JSONBuilder json, private void sendMessage(String msg, @Nullable JSONBuilder json,
...@@ -387,6 +422,9 @@ public class DDPClientImpl { ...@@ -387,6 +422,9 @@ public class DDPClientImpl {
disposables.add( disposables.add(
flowable.subscribe( flowable.subscribe(
base -> { base -> {
if (base instanceof RxWebSocketCallback.Close) {
task.trySetError(new Exception(((RxWebSocketCallback.Close) base).reason));
}
}, },
err -> { err -> {
task.trySetError(new Exception(err)); task.trySetError(new Exception(err));
......
...@@ -62,14 +62,20 @@ public class RxWebSocket { ...@@ -62,14 +62,20 @@ public class RxWebSocket {
} }
}), }),
BackpressureStrategy.BUFFER BackpressureStrategy.BUFFER
).delay(4, TimeUnit.SECONDS).publish(); ).publish();
} }
public boolean sendText(String message) throws IOException { public boolean sendText(String message) throws IOException {
if (webSocket == null) {
return false;
}
return webSocket.send(message); return webSocket.send(message);
} }
public boolean close(int code, String reason) throws IOException { public boolean close(int code, String reason) throws IOException {
if (webSocket == null) {
return false;
}
return webSocket.close(code, reason); return webSocket.close(code, reason);
} }
} }
...@@ -142,9 +142,15 @@ dependencies { ...@@ -142,9 +142,15 @@ dependencies {
compile "com.github.hotchemi:permissionsdispatcher:$permissionsdispatcherVersion" compile "com.github.hotchemi:permissionsdispatcher:$permissionsdispatcherVersion"
annotationProcessor "com.github.hotchemi:permissionsdispatcher-processor:$permissionsdispatcherVersion" annotationProcessor "com.github.hotchemi:permissionsdispatcher-processor:$permissionsdispatcherVersion"
compile('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') { compile('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
transitive = true; transitive = true;
} }
provided 'com.parse.bolts:bolts-tasks:1.4.0'
provided 'io.reactivex.rxjava2:rxjava:2.1.0'
provided 'io.reactivex:rxjava:1.3.0'
provided "com.github.akarnokd:rxjava2-interop:0.10.2"
} }
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'
...@@ -69,8 +69,18 @@ ...@@ -69,8 +69,18 @@
<action android:name="com.google.android.gms.iid.InstanceID"/> <action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter> </intent-filter>
</service> </service>
<service android:name=".service.TaskService"
android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>
</intent-filter>
</service>
<meta-data <meta-data
android:name="io.fabric.ApiKey" android:name="io.fabric.ApiKey"
android:value="12ac6e94f850aaffcdff52001af77ca415d06a43" /> android:value="12ac6e94f850aaffcdff52001af77ca415d06a43" />
</application> </application>
</manifest> </manifest>
\ No newline at end of file
...@@ -3,11 +3,13 @@ package chat.rocket.android; ...@@ -3,11 +3,13 @@ package chat.rocket.android;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import io.reactivex.BackpressureStrategy; import com.hadisatrio.optional.Optional;
import io.reactivex.Flowable;
import java.util.UUID; import java.util.UUID;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
/** /**
* sharedpreference-based cache. * sharedpreference-based cache.
*/ */
...@@ -51,11 +53,11 @@ public class RocketChatCache { ...@@ -51,11 +53,11 @@ public class RocketChatCache {
return preferences.getString(KEY_PUSH_ID, null); return preferences.getString(KEY_PUSH_ID, null);
} }
public Flowable<String> getSelectedServerHostnamePublisher() { public Flowable<Optional<String>> getSelectedServerHostnamePublisher() {
return getValuePublisher(KEY_SELECTED_SERVER_HOSTNAME); return getValuePublisher(KEY_SELECTED_SERVER_HOSTNAME);
} }
public Flowable<String> getSelectedRoomIdPublisher() { public Flowable<Optional<String>> getSelectedRoomIdPublisher() {
return getValuePublisher(KEY_SELECTED_ROOM_ID); return getValuePublisher(KEY_SELECTED_ROOM_ID);
} }
...@@ -75,12 +77,13 @@ public class RocketChatCache { ...@@ -75,12 +77,13 @@ public class RocketChatCache {
getEditor().putString(key, value).apply(); getEditor().putString(key, value).apply();
} }
private Flowable<String> getValuePublisher(final String key) { private Flowable<Optional<String>> getValuePublisher(final String key) {
return Flowable.create(emitter -> { return Flowable.create(emitter -> {
SharedPreferences.OnSharedPreferenceChangeListener SharedPreferences.OnSharedPreferenceChangeListener
listener = (sharedPreferences, changedKey) -> { listener = (sharedPreferences, changedKey) -> {
if (key.equals(changedKey) && !emitter.isCancelled()) { if (key.equals(changedKey) && !emitter.isCancelled()) {
emitter.onNext(getString(key, null)); String value = getString(key, null);
emitter.onNext(Optional.of(value));
} }
}; };
......
...@@ -4,6 +4,8 @@ import android.content.Intent; ...@@ -4,6 +4,8 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.hadisatrio.optional.Optional;
import java.util.List; import java.util.List;
import chat.rocket.android.LaunchUtil; import chat.rocket.android.LaunchUtil;
...@@ -179,6 +181,7 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity { ...@@ -179,6 +181,7 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
private void subscribeToConfigChanges() { private void subscribeToConfigChanges() {
compositeDisposable.add( compositeDisposable.add(
rocketChatCache.getSelectedServerHostnamePublisher() rocketChatCache.getSelectedServerHostnamePublisher()
.map(Optional::get)
.distinctUntilChanged() .distinctUntilChanged()
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
...@@ -190,6 +193,7 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity { ...@@ -190,6 +193,7 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
compositeDisposable.add( compositeDisposable.add(
rocketChatCache.getSelectedRoomIdPublisher() rocketChatCache.getSelectedRoomIdPublisher()
.map(Optional::get)
.distinctUntilChanged() .distinctUntilChanged()
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
......
...@@ -34,7 +34,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract ...@@ -34,7 +34,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
private StatusTicker statusTicker; private StatusTicker statusTicker;
private MainContract.Presenter presenter; private MainContract.Presenter presenter;
private RoomFragment roomFragment;
@Override @Override
protected int getLayoutContainerForFragment() { protected int getLayoutContainerForFragment() {
...@@ -180,8 +179,7 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract ...@@ -180,8 +179,7 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
@Override @Override
public void showRoom(String hostname, String roomId) { public void showRoom(String hostname, String roomId) {
roomFragment = RoomFragment.create(hostname, roomId); showFragment(RoomFragment.create(hostname, roomId));
showFragment(roomFragment);
closeSidebarIfNeeded(); closeSidebarIfNeeded();
KeyboardHelper.hideSoftKeyboard(this); KeyboardHelper.hideSoftKeyboard(this);
} }
...@@ -224,9 +222,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract ...@@ -224,9 +222,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
@Override @Override
public void showConnectionOk() { public void showConnectionOk() {
statusTicker.updateStatus(StatusTicker.STATUS_DISMISS, null); statusTicker.updateStatus(StatusTicker.STATUS_DISMISS, null);
if (roomFragment != null) {
roomFragment.refreshRoom();
}
} }
//TODO: consider this class to define in layouthelper for more complicated operation. //TODO: consider this class to define in layouthelper for more complicated operation.
......
...@@ -98,8 +98,10 @@ public class MainPresenter extends BasePresenter<MainContract.View> ...@@ -98,8 +98,10 @@ public class MainPresenter extends BasePresenter<MainContract.View>
@Override @Override
public void onRetryLogin() { public void onRetryLogin() {
view.showConnecting(); final Disposable subscription = sessionInteractor.retryLogin()
connectivityManagerApi.keepAliveServer(); .subscribe();
addSubscription(subscription);
} }
private void openRoom() { private void openRoom() {
......
...@@ -15,6 +15,7 @@ import chat.rocket.android_ddp.DDPClient; ...@@ -15,6 +15,7 @@ import chat.rocket.android_ddp.DDPClient;
import chat.rocket.android_ddp.DDPClientCallback; import chat.rocket.android_ddp.DDPClientCallback;
import chat.rocket.android_ddp.DDPSubscription; import chat.rocket.android_ddp.DDPSubscription;
import io.reactivex.Flowable; import io.reactivex.Flowable;
import io.reactivex.Maybe;
/** /**
* DDP client wrapper. * DDP client wrapper.
...@@ -124,4 +125,13 @@ public class DDPClientWrapper { ...@@ -124,4 +125,13 @@ public class DDPClientWrapper {
} }
}); });
} }
/**
* check WebSocket connectivity with ping.
*/
public Maybe<DDPClientCallback.Base> doPing() {
final String pingId = UUID.randomUUID().toString();
RCLog.d("ping[%s] >", pingId);
return ddpClient.doPing(pingId);
}
} }
...@@ -83,6 +83,10 @@ public class MethodCallHelper { ...@@ -83,6 +83,10 @@ public class MethodCallHelper {
return task.continueWithTask(_task -> { return task.continueWithTask(_task -> {
if (_task.isFaulted()) { if (_task.isFaulted()) {
Exception exception = _task.getError(); Exception exception = _task.getError();
// If wet get any error, close the socket to let the RocketChatWebSocketThread aware of it.
// FIXME: when rewriting the network layer we should get rid of this MethodCallHelper
// monolith concept. It decouples a lot the socket from the rest of the app.
ddpClientRef.get().close();
if (exception instanceof MethodCall.Error) { if (exception instanceof MethodCall.Error) {
String errMessageJson = exception.getMessage(); String errMessageJson = exception.getMessage();
if (TextUtils.isEmpty(errMessageJson)) { if (TextUtils.isEmpty(errMessageJson)) {
...@@ -94,7 +98,6 @@ public class MethodCallHelper { ...@@ -94,7 +98,6 @@ public class MethodCallHelper {
if (TwoStepAuthException.TYPE.equals(errType)) { if (TwoStepAuthException.TYPE.equals(errType)) {
return Task.forError(new TwoStepAuthException(errMessage)); return Task.forError(new TwoStepAuthException(errMessage));
} }
return Task.forError(new Exception(errMessage)); return Task.forError(new Exception(errMessage));
} else if (exception instanceof DDPClientCallback.RPC.Error) { } else if (exception instanceof DDPClientCallback.RPC.Error) {
String errMessage = ((DDPClientCallback.RPC.Error) exception).error.getString("message"); String errMessage = ((DDPClientCallback.RPC.Error) exception).error.getString("message");
......
...@@ -602,8 +602,4 @@ public class RoomFragment extends AbstractChatRoomFragment implements ...@@ -602,8 +602,4 @@ public class RoomFragment extends AbstractChatRoomFragment implements
edittingMessage = message; edittingMessage = message;
messageFormManager.setEditMessage(message.getMessage()); messageFormManager.setEditMessage(message.getMessage());
} }
public void refreshRoom() {
presenter.loadMessages();
}
} }
\ No newline at end of file
...@@ -63,6 +63,7 @@ import rx.subjects.PublishSubject; ...@@ -63,6 +63,7 @@ import rx.subjects.PublishSubject;
} }
} }
@DebugLog
@Override @Override
public void ensureConnections() { public void ensureConnections() {
for (String hostname : serverConnectivityList.keySet()) { for (String hostname : serverConnectivityList.keySet()) {
...@@ -146,6 +147,7 @@ import rx.subjects.PublishSubject; ...@@ -146,6 +147,7 @@ import rx.subjects.PublishSubject;
return Observable.concat(Observable.from(getCurrentConnectivityList()), connectivitySubject); return Observable.concat(Observable.from(getCurrentConnectivityList()), connectivitySubject);
} }
@DebugLog
private Single<Boolean> connectToServerIfNeeded(String hostname, boolean forceConnect) { private Single<Boolean> connectToServerIfNeeded(String hostname, boolean forceConnect) {
return Single.defer(() -> { return Single.defer(() -> {
final int connectivity = serverConnectivityList.get(hostname); final int connectivity = serverConnectivityList.get(hostname);
...@@ -163,8 +165,8 @@ import rx.subjects.PublishSubject; ...@@ -163,8 +165,8 @@ import rx.subjects.PublishSubject;
} }
return connectToServer(hostname) return connectToServer(hostname)
//.doOnError(RCLog::e) .doOnError(RCLog::e)
.retryWhen(RxHelper.exponentialBackoff(3, 500, TimeUnit.MILLISECONDS)); .retryWhen(RxHelper.exponentialBackoff(Integer.MAX_VALUE, 500, TimeUnit.MILLISECONDS));
}); });
} }
...@@ -191,7 +193,7 @@ import rx.subjects.PublishSubject; ...@@ -191,7 +193,7 @@ import rx.subjects.PublishSubject;
}); });
} }
@DebugLog
private Single<Boolean> waitForConnected(String hostname) { private Single<Boolean> waitForConnected(String hostname) {
return connectivitySubject return connectivitySubject
.filter(serverConnectivity -> hostname.equals(serverConnectivity.hostname)) .filter(serverConnectivity -> hostname.equals(serverConnectivity.hostname))
...@@ -207,6 +209,7 @@ import rx.subjects.PublishSubject; ...@@ -207,6 +209,7 @@ import rx.subjects.PublishSubject;
: Single.error(new ServerConnectivity.DisconnectedException())); : Single.error(new ServerConnectivity.DisconnectedException()));
} }
@DebugLog
private Single<Boolean> waitForDisconnected(String hostname) { private Single<Boolean> waitForDisconnected(String hostname) {
return connectivitySubject return connectivitySubject
.filter(serverConnectivity -> hostname.equals(serverConnectivity.hostname)) .filter(serverConnectivity -> hostname.equals(serverConnectivity.hostname))
......
package chat.rocket.android.service;
import com.google.android.gms.gcm.GcmNetworkManager;
import com.google.android.gms.gcm.GcmTaskService;
import com.google.android.gms.gcm.TaskParams;
public class TaskService extends GcmTaskService {
public static final String TAG_KEEP_ALIVE = "TAG_KEEP_ALIVE";
@Override
public int onRunTask(TaskParams taskParams) {
switch (taskParams.getTag()) {
case TAG_KEEP_ALIVE:
ConnectivityManager.getInstance(getApplicationContext()).keepAliveServer();
return GcmNetworkManager.RESULT_SUCCESS;
default:
return GcmNetworkManager.RESULT_FAILURE;
}
}
}
...@@ -20,7 +20,7 @@ abstract class AbstractBaseSubscriber extends AbstractDDPDocEventSubscriber { ...@@ -20,7 +20,7 @@ abstract class AbstractBaseSubscriber extends AbstractDDPDocEventSubscriber {
@Override @Override
protected final boolean shouldTruncateTableOnInitialize() { protected final boolean shouldTruncateTableOnInitialize() {
return true; return false;
} }
protected abstract String getSubscriptionCallbackName(); protected abstract String getSubscriptionCallbackName();
......
...@@ -2,6 +2,8 @@ package chat.rocket.android.service.internal; ...@@ -2,6 +2,8 @@ package chat.rocket.android.service.internal;
import android.content.Context; import android.content.Context;
import com.hadisatrio.optional.Optional;
import chat.rocket.android.log.RCLog; import chat.rocket.android.log.RCLog;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
...@@ -48,6 +50,7 @@ public abstract class AbstractRocketChatCacheObserver implements Registrable { ...@@ -48,6 +50,7 @@ public abstract class AbstractRocketChatCacheObserver implements Registrable {
compositeDisposable.add( compositeDisposable.add(
new RocketChatCache(context) new RocketChatCache(context)
.getSelectedRoomIdPublisher() .getSelectedRoomIdPublisher()
.map(Optional::get)
.subscribe(this::updateRoomIdWith, RCLog::e) .subscribe(this::updateRoomIdWith, RCLog::e)
); );
} }
......
...@@ -4,6 +4,7 @@ import android.content.Context; ...@@ -4,6 +4,7 @@ import android.content.Context;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import chat.rocket.android.RocketChatCache;
import chat.rocket.persistence.realm.RealmHelper; import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.android.service.DDPClientRef; import chat.rocket.android.service.DDPClientRef;
import chat.rocket.android.service.Registrable; import chat.rocket.android.service.Registrable;
...@@ -19,6 +20,7 @@ public class StreamRoomMessageManager implements Registrable { ...@@ -19,6 +20,7 @@ public class StreamRoomMessageManager implements Registrable {
private final DDPClientRef ddpClientRef; private final DDPClientRef ddpClientRef;
private final AbstractRocketChatCacheObserver cacheObserver; private final AbstractRocketChatCacheObserver cacheObserver;
private final Handler handler; private final Handler handler;
private final RocketChatCache rocketChatCache;
private StreamRoomMessage streamRoomMessage; private StreamRoomMessage streamRoomMessage;
public StreamRoomMessageManager(Context context, String hostname, public StreamRoomMessageManager(Context context, String hostname,
...@@ -27,6 +29,7 @@ public class StreamRoomMessageManager implements Registrable { ...@@ -27,6 +29,7 @@ public class StreamRoomMessageManager implements Registrable {
this.hostname = hostname; this.hostname = hostname;
this.realmHelper = realmHelper; this.realmHelper = realmHelper;
this.ddpClientRef = ddpClientRef; this.ddpClientRef = ddpClientRef;
this.rocketChatCache = new RocketChatCache(context);
cacheObserver = new AbstractRocketChatCacheObserver(context, realmHelper) { cacheObserver = new AbstractRocketChatCacheObserver(context, realmHelper) {
@Override @Override
...@@ -57,6 +60,11 @@ public class StreamRoomMessageManager implements Registrable { ...@@ -57,6 +60,11 @@ public class StreamRoomMessageManager implements Registrable {
@Override @Override
public void register() { public void register() {
cacheObserver.register(); cacheObserver.register();
String selectedRoomId = rocketChatCache.getSelectedRoomId();
if (selectedRoomId == null) {
return;
}
registerStreamNotifyMessage(selectedRoomId);
} }
@Override @Override
......
...@@ -135,13 +135,15 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe ...@@ -135,13 +135,15 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()), () -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(pair.first.where(RealmMessage.class) pair -> RxJavaInterop.toV2Flowable(pair.first.where(RealmMessage.class)
.equalTo(RealmMessage.ROOM_ID, room.getRoomId()) .equalTo(RealmMessage.ROOM_ID, room.getRoomId())
.isNotNull(RealmMessage.USER)
.findAllSorted(RealmMessage.TIMESTAMP, Sort.DESCENDING) .findAllSorted(RealmMessage.TIMESTAMP, Sort.DESCENDING)
.asObservable()), .asObservable()),
pair -> close(pair.first, pair.second) pair -> close(pair.first, pair.second)
) )
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper())) .unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()))
.filter(it -> it.isLoaded() && it.isValid()) .filter(it -> it.isLoaded() && it.isValid())
.map(this::toList)); .map(this::toList)
.distinctUntilChanged());
} }
@Override @Override
......
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