Commit 9ac83d10 authored by Tiago Cunha's avatar Tiago Cunha

Untagles the modules and updates dependencies

Using RxJava2
parent 1c0e06e7
......@@ -2,42 +2,50 @@ apply plugin: 'com.android.library'
apply plugin: 'me.tatarka.retrolambda'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath rootProject.ext.androidPlugin
classpath rootProject.ext.retroLambdaPlugin
classpath rootProject.ext.retroLambdaPatch
}
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'me.tatarka:gradle-retrolambda:3.5.0'
classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
}
}
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.compileSdkVersion
versionCode 1
versionName "0.0.8"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
compileSdkVersion 25
buildToolsVersion '25.0.2'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "0.0.8"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
}
ext {
supportVersion = '25.1.1'
}
dependencies {
compile project(':log-wrapper')
compile rootProject.ext.supportAnnotations
compile rootProject.ext.okhttp3
compile rootProject.ext.rxJava
compile rootProject.ext.boltsTask
compile project(':log-wrapper')
compile "com.android.support:support-annotations:$supportVersion"
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'io.reactivex.rxjava2:rxjava:2.0.6'
compile 'com.parse.bolts:bolts-tasks:1.4.0'
}
package chat.rocket.android_ddp;
import android.support.annotation.Nullable;
import io.reactivex.Flowable;
import org.json.JSONArray;
import bolts.Task;
import bolts.TaskCompletionSource;
import chat.rocket.android_ddp.rx.RxWebSocketCallback;
import okhttp3.OkHttpClient;
import rx.Observable;
public class DDPClient {
// reference: https://github.com/eddflrs/meteor-ddp/blob/master/meteor-ddp.js
......@@ -53,7 +53,7 @@ public class DDPClient {
return task.getTask();
}
public Observable<DDPSubscription.Event> getSubscriptionCallback() {
public Flowable<DDPSubscription.Event> getSubscriptionCallback() {
return impl.getDDPSubscription();
}
......
......@@ -3,6 +3,8 @@ package chat.rocket.android_ddp;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import io.reactivex.Flowable;
import io.reactivex.disposables.CompositeDisposable;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
......@@ -15,15 +17,12 @@ import chat.rocket.android.log.RCLog;
import chat.rocket.android_ddp.rx.RxWebSocket;
import chat.rocket.android_ddp.rx.RxWebSocketCallback;
import okhttp3.OkHttpClient;
import rx.Observable;
import rx.functions.Func1;
import rx.subscriptions.CompositeSubscription;
public class DDPClientImpl {
private final DDPClient client;
private final RxWebSocket websocket;
private Observable<RxWebSocketCallback.Base> observable;
private CompositeSubscription subscriptions;
private Flowable<RxWebSocketCallback.Base> flowable;
private CompositeDisposable subscriptions;
public DDPClientImpl(DDPClient self, OkHttpClient client) {
websocket = new RxWebSocket(client);
......@@ -52,10 +51,10 @@ public class DDPClientImpl {
public void connect(final TaskCompletionSource<DDPClientCallback.Connect> task, final String url,
String session) {
try {
observable = websocket.connect(url).autoConnect();
CompositeSubscription subscriptions = new CompositeSubscription();
flowable = websocket.connect(url).autoConnect();
CompositeDisposable subscriptions = new CompositeDisposable();
subscriptions.add(observable.filter(callback -> callback instanceof RxWebSocketCallback.Open)
subscriptions.add(flowable.filter(callback -> callback instanceof RxWebSocketCallback.Open)
.subscribe(callback -> {
sendMessage("connect",
json -> (TextUtils.isEmpty(session) ? json : json.put("session", session)).put(
......@@ -65,7 +64,7 @@ public class DDPClientImpl {
}));
subscriptions.add(
observable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson)
.timeout(7, TimeUnit.SECONDS)
......@@ -74,15 +73,15 @@ public class DDPClientImpl {
if ("connected".equals(msg) && !response.isNull("session")) {
task.trySetResult(
new DDPClientCallback.Connect(client, response.optString("session")));
subscriptions.unsubscribe();
subscriptions.dispose();
} else if ("error".equals(msg) && "Already connected".equals(
response.optString("reason"))) {
task.trySetResult(new DDPClientCallback.Connect(client, null));
subscriptions.unsubscribe();
subscriptions.dispose();
} else if ("failed".equals(msg)) {
task.trySetError(
new DDPClientCallback.Connect.Failed(client, response.optString("version")));
subscriptions.unsubscribe();
subscriptions.dispose();
}
}, err -> {
task.trySetError(new DDPClientCallback.Connect.Timeout(client));
......@@ -104,10 +103,10 @@ public class DDPClientImpl {
sendMessage("ping", json -> json.put("id", id));
if (requested) {
CompositeSubscription subscriptions = new CompositeSubscription();
CompositeDisposable subscriptions = new CompositeDisposable();
subscriptions.add(
observable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson)
.timeout(4, TimeUnit.SECONDS)
......@@ -116,12 +115,12 @@ public class DDPClientImpl {
if ("pong".equals(msg)) {
if (response.isNull("id")) {
task.setResult(new DDPClientCallback.Ping(client, null));
subscriptions.unsubscribe();
subscriptions.dispose();
} else {
String _id = response.optString("id");
if (id.equals(_id)) {
task.setResult(new DDPClientCallback.Ping(client, id));
subscriptions.unsubscribe();
subscriptions.dispose();
}
}
}
......@@ -141,10 +140,10 @@ public class DDPClientImpl {
sendMessage("sub", json -> json.put("id", id).put("name", name).put("params", params));
if (requested) {
CompositeSubscription subscriptions = new CompositeSubscription();
CompositeDisposable subscriptions = new CompositeDisposable();
subscriptions.add(
observable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson)
.subscribe(response -> {
......@@ -155,7 +154,7 @@ public class DDPClientImpl {
String _id = ids.optString(i);
if (id.equals(_id)) {
task.setResult(new DDPSubscription.Ready(client, id));
subscriptions.unsubscribe();
subscriptions.dispose();
break;
}
}
......@@ -165,7 +164,7 @@ public class DDPClientImpl {
if (id.equals(_id)) {
task.setError(new DDPSubscription.NoSub.Error(client, id,
response.optJSONObject("error")));
subscriptions.unsubscribe();
subscriptions.dispose();
}
}
}, err -> {
......@@ -183,10 +182,10 @@ public class DDPClientImpl {
final boolean requested = sendMessage("unsub", json -> json.put("id", id));
if (requested) {
CompositeSubscription subscriptions = new CompositeSubscription();
CompositeDisposable subscriptions = new CompositeDisposable();
subscriptions.add(
observable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson)
.subscribe(response -> {
......@@ -195,7 +194,7 @@ public class DDPClientImpl {
String _id = response.optString("id");
if (id.equals(_id)) {
task.setResult(new DDPSubscription.NoSub(client, id));
subscriptions.unsubscribe();
subscriptions.dispose();
}
}
}, err -> {
......@@ -214,10 +213,10 @@ public class DDPClientImpl {
json -> json.put("method", method).put("params", params).put("id", id));
if (requested) {
CompositeSubscription subscriptions = new CompositeSubscription();
CompositeDisposable subscriptions = new CompositeDisposable();
subscriptions.add(
observable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson)
.timeout(timeoutMs, TimeUnit.MILLISECONDS)
......@@ -233,7 +232,7 @@ public class DDPClientImpl {
String result = response.optString("result");
task.setResult(new DDPClientCallback.RPC(client, id, result));
}
subscriptions.unsubscribe();
subscriptions.dispose();
}
}
}, err -> {
......@@ -250,13 +249,13 @@ public class DDPClientImpl {
private void subscribeBaseListeners() {
if (subscriptions != null &&
subscriptions.hasSubscriptions() && !subscriptions.isUnsubscribed()) {
subscriptions.size() > 0 && !subscriptions.isDisposed()) {
return;
}
subscriptions = new CompositeSubscription();
subscriptions = new CompositeDisposable();
subscriptions.add(
observable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson)
.subscribe(response -> {
......@@ -272,9 +271,9 @@ public class DDPClientImpl {
}));
}
public Observable<DDPSubscription.Event> getDDPSubscription() {
public Flowable<DDPSubscription.Event> getDDPSubscription() {
String[] targetMsgs = {"added", "changed", "removed", "addedBefore", "movedBefore"};
return observable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
return flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson)
.filter(response -> {
......@@ -286,7 +285,7 @@ public class DDPClientImpl {
}
return false;
})
.map((Func1<JSONObject, DDPSubscription.Event>) response -> {
.map(response -> {
String msg = extractMsg(response);
if ("added".equals(msg)) {
return new DDPSubscription.Added(client, response.optString("collection"),
......@@ -312,20 +311,19 @@ public class DDPClientImpl {
}
return null;
})
.asObservable();
});
}
public void unsubscribeBaseListeners() {
if (subscriptions.hasSubscriptions() && !subscriptions.isUnsubscribed()) {
subscriptions.unsubscribe();
if (subscriptions.size() > 0 || !subscriptions.isDisposed()) {
subscriptions.dispose();
}
}
public Task<RxWebSocketCallback.Close> getOnCloseCallback() {
TaskCompletionSource<RxWebSocketCallback.Close> task = new TaskCompletionSource<>();
observable.filter(callback -> callback instanceof RxWebSocketCallback.Close)
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Close)
.cast(RxWebSocketCallback.Close.class)
.subscribe(task::setResult, err -> {
if (err instanceof Exception) {
......@@ -353,17 +351,17 @@ public class DDPClientImpl {
}
private void sendMessage(String msg, @Nullable JSONBuilder json,
TaskCompletionSource<?> taskForSetError) {
TaskCompletionSource<?> taskForSetError) {
if (!sendMessage(msg, json)) {
taskForSetError.trySetError(new DDPClientCallback.Closed(client));
}
}
private void addErrorCallback(CompositeSubscription subscriptions, TaskCompletionSource<?> task) {
subscriptions.add(observable.subscribe(base -> {
private void addErrorCallback(CompositeDisposable subscriptions, TaskCompletionSource<?> task) {
subscriptions.add(flowable.subscribe(base -> {
}, err -> {
task.trySetError(new Exception(err));
subscriptions.unsubscribe();
subscriptions.dispose();
}));
}
......
package chat.rocket.android_ddp.rx;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.exceptions.OnErrorNotImplementedException;
import io.reactivex.flowables.ConnectableFlowable;
import java.io.IOException;
import chat.rocket.android.log.RCLog;
import okhttp3.OkHttpClient;
......@@ -7,11 +14,6 @@ import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import rx.Emitter;
import rx.Observable;
import rx.exceptions.OnErrorNotImplementedException;
import rx.functions.Action1;
import rx.observables.ConnectableObservable;
public class RxWebSocket {
private OkHttpClient httpClient;
......@@ -21,13 +23,14 @@ public class RxWebSocket {
httpClient = client;
}
public ConnectableObservable<RxWebSocketCallback.Base> connect(String url) {
public ConnectableFlowable<RxWebSocketCallback.Base> connect(String url) {
final Request request = new Request.Builder().url(url).build();
return Observable.fromEmitter(
new Action1<Emitter<RxWebSocketCallback.Base>>() {
return Flowable.create(
new FlowableOnSubscribe<RxWebSocketCallback.Base>() {
@Override
public void call(Emitter<RxWebSocketCallback.Base> emitter) {
public void subscribe(FlowableEmitter<RxWebSocketCallback.Base> emitter)
throws Exception {
httpClient.newWebSocket(request, new WebSocketListener() {
@Override
public void onOpen(WebSocket webSocket, Response response) {
......@@ -52,12 +55,11 @@ public class RxWebSocket {
@Override
public void onClosed(WebSocket webSocket, int code, String reason) {
emitter.onNext(new RxWebSocketCallback.Close(webSocket, code, reason));
emitter.onCompleted();
emitter.onComplete();
}
});
}
},
Emitter.BackpressureMode.BUFFER
}, BackpressureStrategy.BUFFER
).publish();
}
......
......@@ -10,13 +10,13 @@ buildscript {
mavenCentral()
}
dependencies {
classpath rootProject.ext.androidPlugin
classpath 'com.android.tools.build:gradle:2.2.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath rootProject.ext.retroLambdaPlugin
classpath rootProject.ext.retroLambdaPatch
classpath rootProject.ext.realmPlugin
classpath 'me.tatarka:gradle-retrolambda:3.5.0'
classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
classpath 'io.realm:realm-gradle-plugin:2.3.1'
classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
classpath 'com.google.gms:google-services:3.0.0'
classpath 'com.github.triplet.gradle:play-publisher:1.1.5'
......@@ -27,12 +27,12 @@ buildscript {
}
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
applicationId "chat.rocket.android"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.compileSdkVersion
minSdkVersion 16
targetSdkVersion 25
versionCode 9
versionName "1.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
......@@ -66,6 +66,7 @@ android {
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/rxjava.properties'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
......@@ -81,45 +82,56 @@ play {
track = "${track}"
}
ext {
supportVersion = '25.1.1'
playLibVersion = '10.2.0'
stethoVersion = '1.4.2'
rxbindingVersion = '1.0.0'
rxlifecycleVersion = '2.0.1'
icepickVersion = '3.2.0'
permissionsdispatcherVersion = '2.3.1'
}
dependencies {
compile project(':log-wrapper')
compile project(':android-ddp')
compile project(':rocket-chat-core')
compile project(':rocket-chat-android-widgets')
compile project(':persistence-realm')
compile rootProject.ext.supportAppCompat
compile rootProject.ext.supportDesign
compile "com.android.support:appcompat-v7:$supportVersion"
compile "com.android.support:design:$supportVersion"
qaCompile('com.instabug.library:instabug:3.1.0') {
exclude group: 'io.reactivex'
}
compile 'com.android.support:multidex:1.0.1'
compile 'com.google.firebase:firebase-core:10.2.0'
compile 'com.google.firebase:firebase-crash:10.2.0'
compile "com.google.firebase:firebase-core:$playLibVersion"
compile "com.google.firebase:firebase-crash:$playLibVersion"
compile 'com.google.android.gms:play-services-gcm:10.2.0'
compile "com.google.android.gms:play-services-gcm:$playLibVersion"
compile rootProject.ext.okhttp3
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'com.facebook.stetho:stetho:1.4.1'
compile 'com.facebook.stetho:stetho-okhttp3:1.4.1'
compile "com.facebook.stetho:stetho:$stethoVersion"
compile "com.facebook.stetho:stetho-okhttp3:$stethoVersion"
compile 'com.uphyca:stetho_realm:2.0.1'
compile 'com.jakewharton.rxbinding:rxbinding:1.0.0'
compile 'com.jakewharton.rxbinding:rxbinding-support-v4:1.0.0'
compile "com.jakewharton.rxbinding:rxbinding:$rxbindingVersion"
compile "com.jakewharton.rxbinding:rxbinding-support-v4:$rxbindingVersion"
compile 'com.trello:rxlifecycle:1.0'
compile 'com.trello:rxlifecycle-android:1.0'
compile 'com.trello:rxlifecycle-components:1.0'
compile "com.trello.rxlifecycle2:rxlifecycle:$rxlifecycleVersion"
compile "com.trello.rxlifecycle2:rxlifecycle-android:$rxlifecycleVersion"
compile "com.trello.rxlifecycle2:rxlifecycle-components:$rxlifecycleVersion"
compile rootProject.ext.textDrawable
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
compile 'frankiesardo:icepick:3.2.0'
provided 'frankiesardo:icepick-processor:3.2.0'
compile "frankiesardo:icepick:$icepickVersion"
provided "frankiesardo:icepick-processor:$icepickVersion"
compile 'com.github.hotchemi:permissionsdispatcher:2.3.0'
annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:2.3.0'
compile "com.github.hotchemi:permissionsdispatcher:$permissionsdispatcherVersion"
annotationProcessor "com.github.hotchemi:permissionsdispatcher-processor:$permissionsdispatcherVersion"
}
apply plugin: 'com.google.gms.google-services'
......@@ -6,7 +6,8 @@ import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.MotionEvent;
import com.trello.rxlifecycle.components.support.RxAppCompatActivity;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;
import chat.rocket.android.helper.OnBackPressListener;
import chat.rocket.android.log.RCLog;
......
......@@ -2,12 +2,13 @@ package chat.rocket.android.activity;
import android.support.annotation.NonNull;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.service.ConnectivityManagerApi;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.interactors.SessionInteractor;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
public class LoginPresenter extends BasePresenter<LoginContract.View>
implements LoginContract.Presenter {
......@@ -39,7 +40,7 @@ public class LoginPresenter extends BasePresenter<LoginContract.View>
}
private void loadSessionState() {
final Subscription subscription = sessionInteractor.getSessionState()
final Disposable subscription = sessionInteractor.getSessionState()
.distinctUntilChanged()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
......
......@@ -219,10 +219,10 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
}
@Override
public void showUnreadCount(int roomsCount, int mentionsCount) {
public void showUnreadCount(long roomsCount, int mentionsCount) {
RoomToolbar toolbar = (RoomToolbar) findViewById(R.id.activity_main_toolbar);
if (toolbar != null) {
toolbar.setUnreadBudge(roomsCount, mentionsCount);
toolbar.setUnreadBudge((int) roomsCount, mentionsCount);
}
}
......
......@@ -10,7 +10,7 @@ public interface MainContract {
void showRoom(String hostname, String roomId);
void showUnreadCount(int roomsCount, int mentionsCount);
void showUnreadCount(long roomsCount, int mentionsCount);
void showLoginScreen();
......
......@@ -3,14 +3,16 @@ package chat.rocket.android.activity;
import android.support.annotation.NonNull;
import android.support.v4.util.Pair;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.interactors.CanCreateRoomInteractor;
import chat.rocket.core.interactors.RoomInteractor;
import chat.rocket.core.interactors.SessionInteractor;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import chat.rocket.core.models.Session;
public class MainPresenter extends BasePresenter<MainContract.View>
implements MainContract.Presenter {
......@@ -37,7 +39,7 @@ public class MainPresenter extends BasePresenter<MainContract.View>
@Override
public void onOpenRoom(String hostname, String roomId) {
final Subscription subscription = canCreateRoomInteractor.canCreate(roomId)
final Disposable subscription = canCreateRoomInteractor.canCreate(roomId)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(allowed -> {
......@@ -53,14 +55,14 @@ public class MainPresenter extends BasePresenter<MainContract.View>
@Override
public void onRetryLogin() {
final Subscription subscription = sessionInteractor.retryLogin()
final Disposable subscription = sessionInteractor.retryLogin()
.subscribe();
addSubscription(subscription);
}
private void subscribeToUnreadCount() {
final Subscription subscription = Observable.combineLatest(
final Disposable subscription = Flowable.combineLatest(
roomInteractor.getTotalUnreadRoomsCount(),
roomInteractor.getTotalUnreadMentionsCount(),
(Pair::new)
......@@ -73,10 +75,11 @@ public class MainPresenter extends BasePresenter<MainContract.View>
}
private void subscribeToSession() {
final Subscription subscription = sessionInteractor.getDefault()
final Disposable subscription = sessionInteractor.getDefault()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(session -> {
.subscribe(sessionOptional -> {
Session session = sessionOptional.orNull();
if (session == null || session.getToken() == null) {
view.showLoginScreen();
return;
......
package chat.rocket.android.api;
import android.support.annotation.Nullable;
import io.reactivex.Flowable;
import org.json.JSONArray;
import org.json.JSONException;
......@@ -12,7 +13,6 @@ import chat.rocket.android.log.RCLog;
import chat.rocket.android_ddp.DDPClient;
import chat.rocket.android_ddp.DDPClientCallback;
import chat.rocket.android_ddp.DDPSubscription;
import rx.Observable;
/**
* DDP client wrapper.
......@@ -69,7 +69,7 @@ public class DDPClientWrapper {
/**
* Returns Observable for handling DDP subscription.
*/
public Observable<DDPSubscription.Event> getSubscriptionCallback() {
public Flowable<DDPSubscription.Event> getSubscriptionCallback() {
return ddpClient.getSubscriptionCallback();
}
......
......@@ -2,6 +2,9 @@ package chat.rocket.android.api.rest;
import android.support.annotation.NonNull;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import org.json.JSONObject;
import java.io.IOException;
......@@ -9,8 +12,6 @@ import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.ResponseBody;
import rx.Emitter;
import rx.Observable;
public class DefaultServerPolicyApi implements ServerPolicyApi {
......@@ -25,23 +26,23 @@ public class DefaultServerPolicyApi implements ServerPolicyApi {
}
@Override
public Observable<Response<JSONObject>> getApiInfoSecurely() {
public Flowable<Response<JSONObject>> getApiInfoSecurely() {
return getApiInfo(SECURE_PROTOCOL);
}
@Override
public Observable<Response<JSONObject>> getApiInfoInsecurely() {
public Flowable<Response<JSONObject>> getApiInfoInsecurely() {
return getApiInfo(INSECURE_PROTOCOL);
}
private Observable<Response<JSONObject>> getApiInfo(@NonNull String protocol) {
return Observable.fromEmitter(responseEmitter -> {
private Flowable<Response<JSONObject>> getApiInfo(@NonNull String protocol) {
return Flowable.create(responseEmitter -> {
final Call call = client.newCall(createRequest(protocol));
call.enqueue(getOkHttpCallback(responseEmitter, protocol));
responseEmitter.setCancellation(call::cancel);
}, Emitter.BackpressureMode.LATEST);
responseEmitter.setCancellable(call::cancel);
}, BackpressureStrategy.LATEST);
}
private Request createRequest(@NonNull String protocol) {
......@@ -51,7 +52,7 @@ public class DefaultServerPolicyApi implements ServerPolicyApi {
.build();
}
private okhttp3.Callback getOkHttpCallback(@NonNull Emitter<Response<JSONObject>> emitter,
private okhttp3.Callback getOkHttpCallback(@NonNull FlowableEmitter<Response<JSONObject>> emitter,
@NonNull String protocol) {
return new okhttp3.Callback() {
@Override
......@@ -63,14 +64,14 @@ public class DefaultServerPolicyApi implements ServerPolicyApi {
public void onResponse(Call call, okhttp3.Response response) throws IOException {
if (!response.isSuccessful()) {
emitter.onNext(new Response<>(false, protocol, null));
emitter.onCompleted();
emitter.onComplete();
return;
}
final ResponseBody body = response.body();
if (body == null || body.contentLength() == 0) {
emitter.onNext(new Response<>(false, protocol, null));
emitter.onCompleted();
emitter.onComplete();
return;
}
......@@ -80,7 +81,7 @@ public class DefaultServerPolicyApi implements ServerPolicyApi {
emitter.onNext(new Response<>(false, protocol, null));
}
emitter.onCompleted();
emitter.onComplete();
}
};
}
......
package chat.rocket.android.api.rest;
import io.reactivex.Flowable;
import org.json.JSONObject;
import rx.Observable;
public interface ServerPolicyApi {
String SECURE_PROTOCOL = "https://";
String INSECURE_PROTOCOL = "http://";
Observable<Response<JSONObject>> getApiInfoSecurely();
Flowable<Response<JSONObject>> getApiInfoSecurely();
Observable<Response<JSONObject>> getApiInfoInsecurely();
Flowable<Response<JSONObject>> getApiInfoInsecurely();
}
......@@ -6,7 +6,7 @@ import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.trello.rxlifecycle.components.support.RxFragment;
import com.trello.rxlifecycle2.components.support.RxFragment;
/**
* Fragment base class for this Application.
......
......@@ -2,6 +2,10 @@ package chat.rocket.android.fragment.add_server;
import android.content.SharedPreferences;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import chat.rocket.android.RocketChatCache;
import chat.rocket.android.api.rest.DefaultServerPolicyApi;
import chat.rocket.android.api.rest.ServerPolicyApi;
......@@ -10,9 +14,6 @@ import chat.rocket.android.helper.ServerPolicyApiValidationHelper;
import chat.rocket.android.helper.ServerPolicyHelper;
import chat.rocket.android.service.ConnectivityManagerApi;
import chat.rocket.android.shared.BasePresenter;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class InputHostnamePresenter extends BasePresenter<InputHostnameContract.View>
implements InputHostnameContract.Presenter {
......@@ -40,9 +41,9 @@ public class InputHostnamePresenter extends BasePresenter<InputHostnameContract.
final ServerPolicyApiValidationHelper validationHelper =
new ServerPolicyApiValidationHelper(serverPolicyApi);
clearSubscripions();
clearSubscriptions();
final Subscription subscription = ServerPolicyHelper.isApiVersionValid(validationHelper)
final Disposable subscription = ServerPolicyHelper.isApiVersionValid(validationHelper)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnTerminate(() -> view.hideLoader())
......
......@@ -19,6 +19,7 @@ import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.jakewharton.rxbinding.support.v4.widget.RxDrawerLayout;
import java.lang.reflect.Field;
......@@ -56,6 +57,7 @@ import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.android.widget.internal.ExtraActionPickerDialogFragment;
import chat.rocket.android.widget.message.MessageFormLayout;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.RuntimePermissions;
......@@ -233,7 +235,7 @@ public class RoomFragment extends AbstractChatRoomFragment
DrawerLayout drawerLayout = (DrawerLayout) rootView.findViewById(R.id.drawer_layout);
SlidingPaneLayout pane = (SlidingPaneLayout) getActivity().findViewById(R.id.sliding_pane);
if (drawerLayout != null && pane != null) {
RxDrawerLayout.drawerOpen(drawerLayout, GravityCompat.END)
RxJavaInterop.toV2Flowable(RxDrawerLayout.drawerOpen(drawerLayout, GravityCompat.END))
.compose(bindToLifecycle())
.subscribe(opened -> {
try {
......
......@@ -4,6 +4,11 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.Pair;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.helper.LogIfError;
......@@ -16,9 +21,6 @@ import chat.rocket.core.models.User;
import chat.rocket.core.repositories.RoomRepository;
import chat.rocket.core.repositories.UserRepository;
import chat.rocket.android.service.ConnectivityManagerApi;
import rx.Single;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
public class RoomPresenter extends BasePresenter<RoomContract.View>
implements RoomContract.Presenter {
......@@ -55,7 +57,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
@Override
public void loadMessages() {
final Subscription subscription = getSingleRoom()
final Disposable subscription = getSingleRoom()
.flatMap(messageInteractor::loadMessages)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
......@@ -71,7 +73,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
@Override
public void loadMoreMessages() {
final Subscription subscription = getSingleRoom()
final Disposable subscription = getSingleRoom()
.flatMap(messageInteractor::loadMoreMessages)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
......@@ -97,7 +99,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
@Override
public void sendMessage(String messageText) {
final Subscription subscription = getRoomUserPair()
final Disposable subscription = getRoomUserPair()
.flatMap(pair -> messageInteractor.send(pair.first, pair.second, messageText))
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
......@@ -112,7 +114,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
@Override
public void resendMessage(Message message) {
final Subscription subscription = messageInteractor.resend(message)
final Disposable subscription = messageInteractor.resend(message)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
......@@ -122,7 +124,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
@Override
public void deleteMessage(Message message) {
final Subscription subscription = messageInteractor.delete(message)
final Disposable subscription = messageInteractor.delete(message)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
......@@ -132,7 +134,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
@Override
public void onUnreadCount() {
final Subscription subscription = getRoomUserPair()
final Disposable subscription = getRoomUserPair()
.flatMap(roomUserPair -> messageInteractor
.unreadCountFor(roomUserPair.first, roomUserPair.second))
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
......@@ -146,8 +148,8 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
@Override
public void onMarkAsRead() {
final Subscription subscription = roomRepository.getById(roomId)
.first()
final Disposable subscription = roomRepository.getById(roomId)
.firstElement()
.filter(room -> room != null && room.isAlert())
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
......@@ -160,7 +162,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
}
private void getRoomInfo() {
final Subscription subscription = roomRepository.getById(roomId)
final Disposable subscription = roomRepository.getById(roomId)
.distinctUntilChanged()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
......@@ -172,7 +174,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
}
private void getRoomHistoryStateInfo() {
final Subscription subscription = roomRepository.getHistoryStateByRoomId(roomId)
final Disposable subscription = roomRepository.getHistoryStateByRoomId(roomId)
.distinctUntilChanged()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
......@@ -190,8 +192,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
}
private void getMessages() {
final Subscription subscription = roomRepository.getById(roomId)
.first()
final Disposable subscription = roomRepository.getById(roomId)
.flatMap(messageInteractor::getAllFrom)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
......@@ -204,8 +205,9 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
return Single.zip(
getSingleRoom(),
userRepository.getCurrent()
.filter(user -> user != null)
.first()
.filter(Optional::isPresent)
.map(Optional::get)
.firstElement()
.toSingle(),
Pair::new
);
......@@ -213,7 +215,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
private Single<Room> getSingleRoom() {
return roomRepository.getById(roomId)
.first()
.firstElement()
.toSingle();
}
}
......@@ -8,7 +8,6 @@ import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.widget.RxCompoundButton;
import java.util.List;
......@@ -29,6 +28,7 @@ import chat.rocket.android.renderer.UserRenderer;
import chat.rocket.persistence.realm.repositories.RealmRoomRepository;
import chat.rocket.persistence.realm.repositories.RealmUserRepository;
import chat.rocket.android.widget.RocketChatAvatar;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
public class SidebarMainFragment extends AbstractFragment implements SidebarMainContract.View {
......@@ -115,9 +115,12 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
rootView.findViewById(R.id.user_info_container).setOnClickListener(view -> {
toggleUserAction.toggle();
});
RxCompoundButton.checkedChanges(toggleUserAction)
RxJavaInterop.toV2Flowable(RxCompoundButton.checkedChanges(toggleUserAction))
.compose(bindToLifecycle())
.subscribe(RxView.visibility(rootView.findViewById(R.id.user_action_outer_container)));
.subscribe(aBoolean -> {
rootView.findViewById(R.id.user_action_outer_container)
.setVisibility(aBoolean ? View.VISIBLE : View.GONE);
});
}
private void setupUserStatusButtons() {
......
......@@ -2,6 +2,9 @@ package chat.rocket.android.fragment.sidebar;
import android.support.annotation.NonNull;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.helper.LogIfError;
......@@ -10,8 +13,6 @@ import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.interactors.RoomInteractor;
import chat.rocket.core.models.User;
import chat.rocket.core.repositories.UserRepository;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View>
implements SidebarMainContract.Presenter {
......@@ -72,7 +73,7 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View
}
private void subscribeToRooms() {
final Subscription subscription = roomInteractor.getOpenRooms()
final Disposable subscription = roomInteractor.getOpenRooms()
.distinctUntilChanged()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
......@@ -84,11 +85,11 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View
}
private void subscribeToUser() {
final Subscription subscription = userRepository.getCurrent()
final Disposable subscription = userRepository.getCurrent()
.distinctUntilChanged()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(user -> view.showUser(user));
.subscribe(userOptional -> view.showUser(userOptional.orNull()));
addSubscription(subscription);
}
......
......@@ -7,7 +7,8 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.Toast;
import com.trello.rxlifecycle.components.support.RxAppCompatDialogFragment;
import com.trello.rxlifecycle2.components.support.RxAppCompatDialogFragment;
import bolts.Task;
import chat.rocket.android.R;
......
......@@ -4,12 +4,12 @@ import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.TextView;
import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.widget.RxTextView;
import bolts.Task;
import chat.rocket.android.R;
import chat.rocket.android.helper.TextUtils;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
/**
* add Channel, add Private-group.
......@@ -36,10 +36,11 @@ public class AddChannelDialogFragment extends AbstractAddRoomDialogFragment {
protected void onSetupDialog() {
View buttonAddChannel = getDialog().findViewById(R.id.btn_add_channel);
RxTextView.textChanges((TextView) getDialog().findViewById(R.id.editor_channel_name))
RxJavaInterop.toV2Flowable(
RxTextView.textChanges((TextView) getDialog().findViewById(R.id.editor_channel_name)))
.map(text -> !TextUtils.isEmpty(text))
.compose(bindToLifecycle())
.subscribe(RxView.enabled(buttonAddChannel));
.subscribe(buttonAddChannel::setEnabled);
buttonAddChannel.setOnClickListener(view -> createRoom());
}
......
......@@ -4,7 +4,6 @@ import android.os.Bundle;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;
import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.widget.RxTextView;
import io.realm.Case;
......@@ -14,6 +13,7 @@ import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.sidebar.dialog.SuggestUserAdapter;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.RealmAutoCompleteAdapter;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
/**
* add Direct RealmMessage.
......@@ -39,17 +39,18 @@ public class AddDirectMessageDialogFragment extends AbstractAddRoomDialogFragmen
AutoCompleteTextView autoCompleteTextView =
(AutoCompleteTextView) getDialog().findViewById(R.id.editor_username);
RealmAutoCompleteAdapter<RealmUser> adapter = realmHelper.createAutoCompleteAdapter(getContext(),
(realm, text) -> realm.where(RealmUser.class)
.contains(RealmUser.USERNAME, text, Case.INSENSITIVE)
.findAllSorted(RealmUser.USERNAME),
context -> new SuggestUserAdapter(context, hostname));
RealmAutoCompleteAdapter<RealmUser> adapter =
realmHelper.createAutoCompleteAdapter(getContext(),
(realm, text) -> realm.where(RealmUser.class)
.contains(RealmUser.USERNAME, text, Case.INSENSITIVE)
.findAllSorted(RealmUser.USERNAME),
context -> new SuggestUserAdapter(context, hostname));
autoCompleteTextView.setAdapter(adapter);
RxTextView.textChanges(autoCompleteTextView)
RxJavaInterop.toV2Flowable(RxTextView.textChanges(autoCompleteTextView))
.map(text -> !TextUtils.isEmpty(text))
.compose(bindToLifecycle())
.subscribe(RxView.enabled(buttonAddDirectMessage));
.subscribe(buttonAddDirectMessage::setEnabled);
buttonAddDirectMessage.setOnClickListener(view -> createRoom());
}
......
......@@ -2,8 +2,9 @@ package chat.rocket.android.helper;
import android.support.annotation.NonNull;
import io.reactivex.Flowable;
import chat.rocket.android.api.rest.ServerPolicyApi;
import rx.Observable;
public class ServerPolicyApiValidationHelper {
......@@ -13,7 +14,7 @@ public class ServerPolicyApiValidationHelper {
this.serverPolicyApi = serverPolicyApi;
}
public Observable<ServerPolicyHelper.ServerInfoResponse> getApiVersion() {
public Flowable<ServerPolicyHelper.ServerInfoResponse> getApiVersion() {
return serverPolicyApi.getApiInfoSecurely()
.onErrorResumeNext(serverPolicyApi.getApiInfoInsecurely())
.map(response -> new ServerPolicyHelper.ServerInfoResponse(
......
......@@ -2,10 +2,9 @@ package chat.rocket.android.helper;
import android.support.annotation.NonNull;
import io.reactivex.Flowable;
import org.json.JSONObject;
import rx.Observable;
public class ServerPolicyHelper {
private static final String DEFAULT_HOST = ".rocket.chat";
......@@ -19,7 +18,7 @@ public class ServerPolicyHelper {
return removeTrailingSlash(removeProtocol(enforceDefaultHost(hostname)));
}
public static Observable<ServerValidation> isApiVersionValid(
public static Flowable<ServerValidation> isApiVersionValid(
@NonNull ServerPolicyApiValidationHelper serverPolicyApiValidationHelper) {
return serverPolicyApiValidationHelper.getApiVersion()
.map(serverInfo ->
......
......@@ -2,6 +2,7 @@ package chat.rocket.android.service.ddp;
import android.content.Context;
import android.text.TextUtils;
import io.reactivex.disposables.Disposable;
import io.realm.Realm;
import io.realm.RealmObject;
import org.json.JSONArray;
......@@ -15,7 +16,6 @@ import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.android.service.DDPClientRef;
import chat.rocket.android.service.Registrable;
import chat.rocket.android_ddp.DDPSubscription;
import rx.Subscription;
public abstract class AbstractDDPDocEventSubscriber implements Registrable {
protected final Context context;
......@@ -24,7 +24,7 @@ public abstract class AbstractDDPDocEventSubscriber implements Registrable {
protected final DDPClientRef ddpClientRef;
private boolean isUnsubscribed;
private String subscriptionId;
private Subscription rxSubscription;
private Disposable rxSubscription;
protected AbstractDDPDocEventSubscriber(Context context, String hostname,
RealmHelper realmHelper, DDPClientRef ddpClientRef) {
......@@ -94,7 +94,7 @@ public abstract class AbstractDDPDocEventSubscriber implements Registrable {
onRegister();
}
protected Subscription subscribe() {
protected Disposable subscribe() {
return ddpClientRef.get().getSubscriptionCallback()
.filter(event -> event instanceof DDPSubscription.DocEvent)
.cast(DDPSubscription.DocEvent.class)
......@@ -179,7 +179,7 @@ public abstract class AbstractDDPDocEventSubscriber implements Registrable {
isUnsubscribed = true;
onUnregister();
if (rxSubscription != null) {
rxSubscription.unsubscribe();
rxSubscription.dispose();
}
if (!TextUtils.isEmpty(subscriptionId)) {
ddpClientRef.get().unsubscribe(subscriptionId).continueWith(new LogIfError());
......
......@@ -2,14 +2,14 @@ package chat.rocket.android.shared;
import android.support.annotation.NonNull;
import rx.Subscription;
import rx.subscriptions.CompositeSubscription;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
public abstract class BasePresenter<T extends BaseContract.View>
implements BaseContract.Presenter<T> {
protected T view;
private CompositeSubscription compositeSubscription = new CompositeSubscription();
private CompositeDisposable compositeSubscription = new CompositeDisposable();
@Override
public void bindView(@NonNull T view) {
......@@ -22,11 +22,11 @@ public abstract class BasePresenter<T extends BaseContract.View>
view = null;
}
protected void addSubscription(Subscription subscription) {
protected void addSubscription(Disposable subscription) {
compositeSubscription.add(subscription);
}
protected void clearSubscripions() {
protected void clearSubscriptions() {
compositeSubscription.clear();
}
}
ext {
androidPlugin = 'com.android.tools.build:gradle:2.2.3'
realmPlugin = 'io.realm:realm-gradle-plugin:2.2.1'
retroLambdaPlugin = 'me.tatarka:gradle-retrolambda:3.3.1'
retroLambdaPatch = 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
compileSdkVersion = 25
buildToolsVersion = '25.0.1'
minSdkVersion = 16
supportVersion = '25.0.1'
supportAnnotations = "com.android.support:support-annotations:$supportVersion"
supportRecyclerView = "com.android.support:recyclerview-v7:$supportVersion"
supportAppCompat = "com.android.support:appcompat-v7:$supportVersion"
supportV13 = "com.android.support:support-v13:$supportVersion"
supportDesign = "com.android.support:design:$supportVersion"
frescoVersion = '1.0.1'
frescoBase = "com.facebook.fresco:fresco:$frescoVersion"
frescoAnimatedGif = "com.facebook.fresco:animated-gif:$frescoVersion"
frescoAnimatedWebp = "com.facebook.fresco:animated-webp:$frescoVersion"
frescoWebp = "com.facebook.fresco:webpsupport:$frescoVersion"
frescoImagePipelineOkHttp3 = "com.facebook.fresco:imagepipeline-okhttp3:$frescoVersion"
rxJava = 'io.reactivex:rxjava:1.2.3'
boltsTask = 'com.parse.bolts:bolts-tasks:1.4.0'
okhttp3 = 'com.squareup.okhttp3:okhttp:3.5.0'
textDrawable = 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
preDexLibs = !"true".equals(System.getenv("CI"))
}
subprojects { project ->
project.configurations.all {
resolutionStrategy {
eachDependency { details ->
if (details.requested.group == 'com.android.support'
&& details.requested.name.indexOf("multidex") == -1) {
details.useVersion(rootProject.ext.supportVersion)
}
}
}
}
preDexLibs = !"true".equals(System.getenv("CI"))
}
subprojects {
project.plugins.whenPluginAdded { plugin ->
if ("com.android.build.gradle.AppPlugin".equals(plugin.class.name)) {
project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs
} else if ("com.android.build.gradle.LibraryPlugin".equals(plugin.class.name)) {
project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs
project.plugins.whenPluginAdded { plugin ->
if ("com.android.build.gradle.AppPlugin".equals(plugin.class.name)) {
project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs
} else if ("com.android.build.gradle.LibraryPlugin".equals(plugin.class.name)) {
project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs
}
}
}
}
\ No newline at end of file
......@@ -5,17 +5,17 @@ buildscript {
jcenter()
}
dependencies {
classpath rootProject.ext.androidPlugin
classpath 'com.android.tools.build:gradle:2.2.3'
}
}
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.compileSdkVersion
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1"
}
......@@ -26,7 +26,3 @@ android {
}
}
}
dependencies {
compile rootProject.ext.supportAnnotations
}
\ No newline at end of file
......@@ -4,48 +4,58 @@ apply plugin: 'com.jakewharton.hugo'
apply plugin: 'me.tatarka.retrolambda'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath rootProject.ext.androidPlugin
classpath rootProject.ext.realmPlugin
classpath rootProject.ext.retroLambdaPlugin
classpath rootProject.ext.retroLambdaPatch
classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
}
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'io.realm:realm-gradle-plugin:2.3.1'
classpath 'me.tatarka:gradle-retrolambda:3.5.0'
classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
}
}
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.compileSdkVersion
versionCode 1
versionName "1"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
compileSdkVersion 25
buildToolsVersion '25.0.2'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
defaultConfig {
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
ext {
supportVersion = '25.1.1'
}
dependencies {
testCompile 'junit:junit:4.12'
compile project(':log-wrapper')
compile project(':rocket-chat-core')
compile 'io.reactivex:rxjava:1.2.3'
compile 'io.reactivex:rxandroid:1.2.1'
compile rootProject.ext.boltsTask
compile rootProject.ext.supportAnnotations
compile rootProject.ext.supportAppCompat
compile rootProject.ext.supportDesign
compile project(':log-wrapper')
compile project(':rocket-chat-core')
compile "com.android.support:support-annotations:$supportVersion"
compile "com.android.support:appcompat-v7:$supportVersion"
compile "com.android.support:design:$supportVersion"
compile 'io.reactivex.rxjava2:rxjava:2.0.6'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.github.akarnokd:rxjava2-interop:0.9.1'
compile 'com.parse.bolts:bolts-tasks:1.4.0'
testCompile 'junit:junit:4.12'
}
package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.Realm;
import io.realm.RealmResults;
import io.realm.Sort;
......@@ -14,9 +19,7 @@ import chat.rocket.core.repositories.MessageRepository;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmMessage;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import rx.Observable;
import rx.Single;
import rx.android.schedulers.AndroidSchedulers;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
public class RealmMessageRepository extends RealmRepository implements MessageRepository {
......@@ -27,34 +30,28 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe
}
@Override
public Single<Message> getById(String messageId) {
return Single.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null || looper == null) {
return Single.just(null);
}
final RealmMessage realmMessage = realm.where(RealmMessage.class)
.equalTo(RealmMessage.ID, messageId)
.findFirst();
if (realmMessage == null) {
realm.close();
return Single.just(null);
}
return realmMessage
.<RealmMessage>asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.filter(it -> it != null && it.isLoaded()
&& it.isValid())
.first()
.toSingle()
.map(RealmMessage::asMessage);
});
public Single<Optional<Message>> getById(String messageId) {
return Single.defer(() -> Flowable.using(
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(
pair.first.where(RealmMessage.class)
.equalTo(RealmMessage.ID, messageId)
.findAll()
.<RealmResults<RealmMessage>>asObservable()),
pair -> close(pair.first, pair.second)
)
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()))
.filter(it -> it != null && it.isLoaded()
&& it.isValid())
.map(realmMessages -> {
if (realmMessages.size() > 0) {
return Optional.of(realmMessages.get(0).asMessage());
}
return Optional.<Message>absent();
})
.firstElement()
.toSingle());
}
@Override
......@@ -92,13 +89,13 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe
realm.beginTransaction();
return realm.copyToRealmOrUpdate(realmMessage)
.asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
return RxJavaInterop.toV2Flowable(realm.copyToRealmOrUpdate(realmMessage)
.asObservable())
.filter(it -> it != null && it.isLoaded() && it.isValid())
.first()
.doOnNext(it -> realm.commitTransaction())
.firstElement()
.doOnSuccess(it -> realm.commitTransaction())
.doOnError(throwable -> realm.cancelTransaction())
.doOnEvent((realmObject, throwable) -> close(realm, looper))
.toSingle()
.map(realmObject -> true);
});
......@@ -116,71 +113,58 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe
realm.beginTransaction();
return realm.where(RealmMessage.class)
return RxJavaInterop.toV2Flowable(realm.where(RealmMessage.class)
.equalTo(RealmMessage.ID, message.getId())
.findAll()
.<RealmResults<RealmMessage>>asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.<RealmResults<RealmMessage>>asObservable())
.filter(realmObject -> realmObject != null
&& realmObject.isLoaded() && realmObject.isValid())
.first()
.firstElement()
.toSingle()
.flatMap(realmMessages -> Single.just(realmMessages.deleteAllFromRealm()))
.doOnEach(notification -> {
if (notification.getValue()) {
.doOnEvent((success, throwable) -> {
if (success) {
realm.commitTransaction();
} else {
realm.cancelTransaction();
}
close(realm, looper);
});
});
}
@Override
public Observable<List<Message>> getAllFrom(Room room) {
return Observable.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null || looper == null) {
return Observable.just(null);
}
return realm.where(RealmMessage.class)
.equalTo(RealmMessage.ROOM_ID, room.getRoomId())
.findAllSorted(RealmMessage.TIMESTAMP, Sort.DESCENDING)
.asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.filter(it -> it != null
&& it.isLoaded() && it.isValid())
.map(this::toList);
});
public Flowable<List<Message>> getAllFrom(Room room) {
return Flowable.defer(() -> Flowable.using(
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(pair.first.where(RealmMessage.class)
.equalTo(RealmMessage.ROOM_ID, room.getRoomId())
.findAllSorted(RealmMessage.TIMESTAMP, Sort.DESCENDING)
.asObservable()),
pair -> close(pair.first, pair.second)
)
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()))
.filter(it -> it != null
&& it.isLoaded() && it.isValid())
.map(this::toList));
}
@Override
public Single<Integer> unreadCountFor(Room room, User user) {
return Single.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null || looper == null) {
return Single.just(0);
}
return realm.where(RealmMessage.class)
.equalTo(RealmMessage.ROOM_ID, room.getId())
.greaterThanOrEqualTo(RealmMessage.TIMESTAMP, room.getLastSeen())
.notEqualTo(RealmMessage.USER_ID, user.getId())
.findAll()
.asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.map(RealmResults::size)
.first()
.toSingle();
});
return Single.defer(() -> Flowable.using(
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(pair.first.where(RealmMessage.class)
.equalTo(RealmMessage.ROOM_ID, room.getId())
.greaterThanOrEqualTo(RealmMessage.TIMESTAMP, room.getLastSeen())
.notEqualTo(RealmMessage.USER_ID, user.getId())
.findAll()
.asObservable()),
pair -> close(pair.first, pair.second)
)
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()))
.map(RealmResults::size)
.firstElement()
.toSingle());
}
private List<Message> toList(RealmResults<RealmMessage> realmMessages) {
......
......@@ -7,6 +7,9 @@ import io.realm.Realm;
public class RealmRepository {
protected void close(Realm realm, Looper looper) {
if (realm == null || looper == null) {
return;
}
new Handler(looper).post(realm::close);
}
}
package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.Realm;
import io.realm.RealmResults;
......@@ -12,9 +16,7 @@ import chat.rocket.core.repositories.RoomRepository;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmRoom;
import chat.rocket.persistence.realm.models.internal.LoadMessageProcedure;
import rx.Observable;
import rx.Single;
import rx.android.schedulers.AndroidSchedulers;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
public class RealmRoomRepository extends RealmRepository implements RoomRepository {
......@@ -25,68 +27,53 @@ public class RealmRoomRepository extends RealmRepository implements RoomReposito
}
@Override
public Observable<List<Room>> getAll() {
return Observable.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null || looper == null) {
return Observable.just(null);
}
return realm.where(RealmRoom.class)
.findAll()
.asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.filter(roomSubscriptions -> roomSubscriptions != null && roomSubscriptions.isLoaded()
&& roomSubscriptions.isValid())
.map(this::toList);
});
public Flowable<List<Room>> getAll() {
return Flowable.defer(() -> Flowable.using(
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(
pair.first.where(RealmRoom.class)
.findAll()
.asObservable()),
pair -> close(pair.first, pair.second)
)
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()))
.filter(roomSubscriptions -> roomSubscriptions != null && roomSubscriptions.isLoaded()
&& roomSubscriptions.isValid())
.map(this::toList));
}
@Override
public Observable<Room> getById(String roomId) {
return Observable.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null || looper == null) {
return Observable.just(null);
}
return realm.where(RealmRoom.class)
.equalTo(RealmRoom.ROOM_ID, roomId)
.findFirst()
.<RealmRoom>asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.filter(roomSubscription -> roomSubscription != null && roomSubscription.isLoaded()
&& roomSubscription.isValid())
.map(RealmRoom::asRoom);
});
public Flowable<Room> getById(String roomId) {
return Flowable.defer(() -> Flowable.using(
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(
pair.first.where(RealmRoom.class)
.equalTo(RealmRoom.ROOM_ID, roomId)
.findFirst()
.<RealmRoom>asObservable()
.filter(roomSubscription -> roomSubscription != null && roomSubscription.isLoaded()
&& roomSubscription.isValid())),
pair -> close(pair.first, pair.second)
)
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()))
.map(RealmRoom::asRoom));
}
@Override
public Observable<RoomHistoryState> getHistoryStateByRoomId(String roomId) {
return Observable.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null || looper == null) {
return Observable.just(null);
}
return realm.where(LoadMessageProcedure.class)
.equalTo(LoadMessageProcedure.ID, roomId)
.findFirst()
.<LoadMessageProcedure>asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.filter(loadMessageProcedure -> loadMessageProcedure != null
&& loadMessageProcedure.isLoaded() && loadMessageProcedure.isValid())
.map(LoadMessageProcedure::asRoomHistoryState);
});
public Flowable<RoomHistoryState> getHistoryStateByRoomId(String roomId) {
return Flowable.defer(() -> Flowable.using(
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(
pair.first.where(LoadMessageProcedure.class)
.equalTo(LoadMessageProcedure.ID, roomId)
.findFirst()
.<LoadMessageProcedure>asObservable()
.filter(loadMessageProcedure -> loadMessageProcedure != null
&& loadMessageProcedure.isLoaded() && loadMessageProcedure.isValid())),
pair -> close(pair.first, pair.second)
)
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()))
.map(LoadMessageProcedure::asRoomHistoryState));
}
@Override
......@@ -109,14 +96,14 @@ public class RealmRoomRepository extends RealmRepository implements RoomReposito
realm.beginTransaction();
return realm.copyToRealmOrUpdate(loadMessage)
.asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
return RxJavaInterop.toV2Flowable(realm.copyToRealmOrUpdate(loadMessage)
.asObservable())
.filter(realmObject -> realmObject != null
&& realmObject.isLoaded() && realmObject.isValid())
.first()
.doOnNext(realmObject -> realm.commitTransaction())
.firstElement()
.doOnSuccess(it -> realm.commitTransaction())
.doOnError(throwable -> realm.cancelTransaction())
.doOnEvent((realmObject, throwable) -> close(realm, looper))
.toSingle()
.map(realmObject -> true);
});
......
package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.Realm;
import chat.rocket.core.models.Session;
import chat.rocket.core.repositories.SessionRepository;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import rx.Observable;
import rx.Single;
import rx.android.schedulers.AndroidSchedulers;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
public class RealmSessionRepository extends RealmRepository implements SessionRepository {
......@@ -20,29 +23,24 @@ public class RealmSessionRepository extends RealmRepository implements SessionRe
}
@Override
public Observable<Session> getById(int id) {
return Observable.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null || looper == null) {
return Observable.just(null);
}
return realm.where(RealmSession.class)
.equalTo(RealmSession.ID, id)
.findAll()
.<RealmSession>asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.filter(it -> it != null && it.isLoaded() && it.isValid())
.map(realmSessions -> {
if (realmSessions.size() == 0) {
return null;
}
return realmSessions.get(0).asSession();
});
});
public Flowable<Optional<Session>> getById(int id) {
return Flowable.defer(() -> Flowable.using(
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(
pair.first.where(RealmSession.class)
.equalTo(RealmSession.ID, id)
.findAll()
.<RealmSession>asObservable()),
pair -> close(pair.first, pair.second)
)
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()))
.filter(it -> it != null && it.isLoaded() && it.isValid())
.map(realmSessions -> {
if (realmSessions.size() == 0) {
return Optional.absent();
}
return Optional.of(realmSessions.get(0).asSession());
}));
}
@Override
......@@ -52,7 +50,7 @@ public class RealmSessionRepository extends RealmRepository implements SessionRe
final Looper looper = Looper.myLooper();
if (realm == null || looper == null) {
return Single.just(null);
return Single.just(false);
}
RealmSession realmSession = realm.where(RealmSession.class)
......@@ -72,13 +70,13 @@ public class RealmSessionRepository extends RealmRepository implements SessionRe
realm.beginTransaction();
return realm.copyToRealmOrUpdate(realmSession)
.asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
return RxJavaInterop.toV2Flowable(realm.copyToRealmOrUpdate(realmSession)
.asObservable())
.filter(it -> it != null && it.isLoaded() && it.isValid())
.first()
.doOnNext(it -> realm.commitTransaction())
.firstElement()
.doOnSuccess(it -> realm.commitTransaction())
.doOnError(throwable -> realm.cancelTransaction())
.doOnEvent((realmObject, throwable) -> close(realm, looper))
.toSingle()
.map(realmObject -> true);
});
......
package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import io.realm.Realm;
import android.support.v4.util.Pair;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.RealmResults;
import chat.rocket.core.models.User;
import chat.rocket.core.repositories.UserRepository;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
public class RealmUserRepository extends RealmRepository implements UserRepository {
......@@ -19,30 +22,25 @@ public class RealmUserRepository extends RealmRepository implements UserReposito
}
@Override
public Observable<User> getCurrent() {
return Observable.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null || looper == null) {
return Observable.just(null);
}
final RealmUser realmUser = realm.where(RealmUser.class)
.isNotEmpty(RealmUser.EMAILS)
.findFirst();
if (realmUser == null) {
realm.close();
return Observable.just(null);
}
return realmUser
.<RealmUser>asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.filter(it -> it != null && it.isLoaded() && it.isValid())
.map(RealmUser::asUser);
});
public Flowable<Optional<User>> getCurrent() {
return Flowable.defer(() -> Flowable.using(
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(
pair.first.where(RealmUser.class)
.isNotEmpty(RealmUser.EMAILS)
.findAll()
.<RealmResults<RealmUser>>asObservable()),
pair -> close(pair.first, pair.second)
)
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()))
.filter(it -> it != null && it.isLoaded()
&& it.isValid())
.map(realmUsers -> {
if (realmUsers.size() > 0) {
return Optional.of(realmUsers.get(0).asUser());
}
return Optional.<User>absent();
}));
}
}
......@@ -5,17 +5,17 @@ buildscript {
jcenter()
}
dependencies {
classpath rootProject.ext.androidPlugin
classpath 'com.android.tools.build:gradle:2.2.3'
}
}
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.compileSdkVersion
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1"
......@@ -29,27 +29,36 @@ android {
}
}
dependencies {
testCompile 'junit:junit:4.12'
compile rootProject.ext.supportAnnotations
compile rootProject.ext.supportAppCompat
compile rootProject.ext.supportV13
compile rootProject.ext.supportDesign
ext {
supportVersion = '25.1.1'
frescoVersion = '1.1.0'
}
dependencies {
compile project(':rocket-chat-core')
compile 'org.nibor.autolink:autolink:0.5.0'
compile "com.android.support:support-annotations:$supportVersion"
compile "com.android.support:appcompat-v7:$supportVersion"
compile "com.android.support:support-v13:$supportVersion"
compile "com.android.support:design:$supportVersion"
compile 'org.nibor.autolink:autolink:0.6.0'
compile rootProject.ext.textDrawable
compile rootProject.ext.okhttp3
compile rootProject.ext.boltsTask
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'com.parse.bolts:bolts-tasks:1.4.0'
compile 'com.github.yusukeiwaki.android-widget:widget-fontawesome:0.0.1'
compile rootProject.ext.frescoBase
compile rootProject.ext.frescoAnimatedGif
compile rootProject.ext.frescoAnimatedWebp
compile rootProject.ext.frescoWebp
compile rootProject.ext.frescoImagePipelineOkHttp3
compile "com.facebook.fresco:fresco:$frescoVersion"
compile "com.facebook.fresco:animated-gif:$frescoVersion"
compile "com.facebook.fresco:animated-webp:$frescoVersion"
compile "com.facebook.fresco:webpsupport:$frescoVersion"
compile "com.facebook.fresco:imagepipeline-okhttp3:$frescoVersion"
compile 'com.caverock:androidsvg:1.2.1'
testCompile 'junit:junit:4.12'
}
......@@ -11,7 +11,9 @@ dependencies {
compile 'com.google.code.findbugs:jsr305:3.0.1'
compile 'io.reactivex:rxjava:1.2.3'
compile 'io.reactivex.rxjava2:rxjava:2.0.6'
compile 'com.fernandocejas:arrow:1.0.0'
compile 'com.google.auto.value:auto-value:1.3'
apt 'com.google.auto.value:auto-value:1.3'
......
package chat.rocket.core.interactors;
import io.reactivex.Flowable;
import io.reactivex.Single;
import chat.rocket.core.repositories.UserRepository;
import rx.Observable;
import rx.Single;
public class CanCreateRoomInteractor {
......@@ -16,13 +17,12 @@ public class CanCreateRoomInteractor {
}
public Single<Boolean> canCreate(String roomId) {
return Observable.zip(
return Flowable.zip(
userRepository.getCurrent(),
sessionInteractor.getDefault(),
Observable.just(roomId),
Flowable.just(roomId),
(user, session, room) -> user != null && session != null && room != null
)
.first()
.toSingle();
.first(false);
}
}
package chat.rocket.core.interactors;
import io.reactivex.Flowable;
import io.reactivex.Single;
import java.util.List;
import java.util.UUID;
import chat.rocket.core.SyncState;
......@@ -9,8 +12,6 @@ import chat.rocket.core.models.RoomHistoryState;
import chat.rocket.core.models.User;
import chat.rocket.core.repositories.MessageRepository;
import chat.rocket.core.repositories.RoomRepository;
import rx.Observable;
import rx.Single;
public class MessageInteractor {
......@@ -42,7 +43,7 @@ public class MessageInteractor {
return !roomHistoryState.isComplete()
&& (syncState == SyncState.SYNCED || syncState == SyncState.FAILED);
})
.first()
.firstElement()
.toSingle()
.flatMap(roomHistoryState -> roomRepository
.setHistoryState(roomHistoryState.withSyncState(SyncState.NOT_SYNCED)));
......@@ -75,7 +76,7 @@ public class MessageInteractor {
return messageRepository.unreadCountFor(room, user);
}
public Observable<List<Message>> getAllFrom(Room room) {
public Flowable<List<Message>> getAllFrom(Room room) {
return messageRepository.getAllFrom(room);
}
}
package chat.rocket.core.interactors;
import io.reactivex.Flowable;
import java.util.List;
import chat.rocket.core.models.Room;
import chat.rocket.core.repositories.RoomRepository;
import rx.Observable;
public class RoomInteractor {
......@@ -13,26 +14,29 @@ public class RoomInteractor {
this.roomRepository = roomRepository;
}
public Observable<Integer> getTotalUnreadMentionsCount() {
public Flowable<Integer> getTotalUnreadMentionsCount() {
return roomRepository.getAll()
.flatMap(rooms -> Observable.from(rooms)
.flatMap(rooms -> Flowable.fromIterable(rooms)
.filter(room -> room.isOpen() && room.isAlert())
.map(Room::getUnread)
.defaultIfEmpty(0)
.reduce((unreadCount, unreadCount2) -> unreadCount + unreadCount2));
.reduce((unreadCount, unreadCount2) -> unreadCount + unreadCount2)
.toFlowable());
}
public Observable<Integer> getTotalUnreadRoomsCount() {
public Flowable<Long> getTotalUnreadRoomsCount() {
return roomRepository.getAll()
.flatMap(rooms -> Observable.from(rooms)
.flatMap(rooms -> Flowable.fromIterable(rooms)
.filter(room -> room.isOpen() && room.isAlert())
.count());
.count()
.toFlowable());
}
public Observable<List<Room>> getOpenRooms() {
public Flowable<List<Room>> getOpenRooms() {
return roomRepository.getAll()
.flatMap(rooms -> Observable.from(rooms)
.flatMap(rooms -> Flowable.fromIterable(rooms)
.filter(Room::isOpen)
.toList());
.toList()
.toFlowable());
}
}
package chat.rocket.core.interactors;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import chat.rocket.core.models.Session;
import chat.rocket.core.repositories.SessionRepository;
import rx.Observable;
import rx.Single;
public class SessionInteractor {
......@@ -15,20 +17,23 @@ public class SessionInteractor {
this.sessionRepository = sessionRepository;
}
public Observable<Session> getDefault() {
public Flowable<Optional<Session>> getDefault() {
return sessionRepository.getById(DEFAULT_ID);
}
public Observable<Session.State> getSessionState() {
public Flowable<Session.State> getSessionState() {
return getDefault()
.map(this::getStateFrom);
.map(sessionOptional -> getStateFrom(sessionOptional.orNull()));
}
public Single<Boolean> retryLogin() {
return getDefault()
.filter(Optional::isPresent)
.map(Optional::get)
.filter(session -> session.getToken() != null
&& (!session.isTokenVerified() || session.getError() != null))
.map(session -> session.withTokenVerified(false).withError(null))
.firstElement()
.toSingle()
.flatMap(sessionRepository::save);
}
......
package chat.rocket.core.repositories;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import java.util.List;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.User;
import rx.Observable;
import rx.Single;
public interface MessageRepository {
Single<Message> getById(String messageId);
Single<Optional<Message>> getById(String messageId);
Single<Boolean> save(Message message);
Single<Boolean> delete(Message message);
Observable<List<Message>> getAllFrom(Room room);
Flowable<List<Message>> getAllFrom(Room room);
Single<Integer> unreadCountFor(Room room, User user);
}
package chat.rocket.core.repositories;
import io.reactivex.Flowable;
import io.reactivex.Single;
import java.util.List;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.RoomHistoryState;
import rx.Observable;
import rx.Single;
public interface RoomRepository {
Observable<List<Room>> getAll();
Flowable<List<Room>> getAll();
Observable<Room> getById(String roomId);
Flowable<Room> getById(String roomId);
Observable<RoomHistoryState> getHistoryStateByRoomId(String roomId);
Flowable<RoomHistoryState> getHistoryStateByRoomId(String roomId);
Single<Boolean> setHistoryState(RoomHistoryState roomHistoryState);
}
package chat.rocket.core.repositories;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import chat.rocket.core.models.Session;
import rx.Observable;
import rx.Single;
public interface SessionRepository {
Observable<Session> getById(int id);
Flowable<Optional<Session>> getById(int id);
Single<Boolean> save(Session session);
}
package chat.rocket.core.repositories;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.Flowable;
import chat.rocket.core.models.User;
import rx.Observable;
public interface UserRepository {
Observable<User> getCurrent();
Flowable<Optional<User>> getCurrent();
}
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