Unverified Commit 975511e9 authored by Leonardo Aramaki's avatar Leonardo Aramaki Committed by GitHub

Merge pull request #575 from RocketChat/fix/crashes-on-beta-versions

Fix most common crashes on Beta versions
parents 07e15c9e 4c3e2167
# -*- coding:utf-8 -*-
a='''
@Override
public void onOpen(WebSocket webSocket, Response response) {
}
@Override
public void onFailure(IOException e, Response response) {
}
@Override
public void onMessage(ResponseBody responseBody) throws IOException {
}
@Override
public void onPong(Buffer payload) {
}
@Override
public void onClose(int code, String reason) {
}
'''.strip().split('@Override')
for m in a[1:]:
m= " @Override\n "+m.strip()
mn = m.split("\n")[1].strip().split(" ")[2].split("(")[0]
if mn.startswith("on"):
d=dict()
d["classname"]=mn[2:]
params = [p for p in " ".join(m.split("\n")[1].strip()[:-1].split(" throws ")[0].split(" ")[2:]).strip()[len(mn)+1:-1].split(", ") if p.split(" ")[0]!="WebSocket"]
d["params"]="".join([", "+p for p in params])
paramnames = [p.split(" ")[-1] for p in params]
d["paramdefs"]="\n".join([" public "+p+";" for p in params])
d["thisis"]="\n".join([" this.{param} = {param};".format(param=p) for p in paramnames])
# print '''
# public static class {classname} extends Base {{
# {paramdefs}
# public {classname}(WebSocket websocket{params}) {{
# super("{classname}", websocket);
# {thisis}
# }}
# }}'''.format(**d)
######################
x=m.split("\n")
x[2]=''' mSubscriber.onNext(new RxWebSocketCallback.{classname}(mWebSocket, {params}));'''.format(classname=mn[2:],params=", ".join(paramnames))
print "\n".join(x)
......@@ -2,6 +2,7 @@ package chat.rocket.android_ddp;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.json.JSONObject;
public class DDPClientCallback {
......
package chat.rocket.android_ddp;
import android.support.annotation.NonNull;
import org.json.JSONArray;
import org.json.JSONObject;
......
package chat.rocket.android_ddp.rx;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import chat.rocket.android.log.RCLog;
import io.reactivex.BackpressureStrategy;
......
......@@ -20,8 +20,8 @@ android {
applicationId "chat.rocket.android"
minSdkVersion 16
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 49
versionName "1.0.26"
versionCode 50
versionName "1.0.27"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
multiDexEnabled true
......@@ -114,19 +114,16 @@ dependencies {
compile extraDependencies.okHTTP
compile extraDependencies.rxJava
compile extraDependencies.boltTask
compile supportDependencies.multidex
compile supportDependencies.designSupportLibrary
compile supportDependencies.annotation
compile supportDependencies.kotlin;
compile rxbindingDependencies.rxBinding
compile rxbindingDependencies.rxBindingSupport
compile rxbindingDependencies.rxBindingAppcompact
compile 'com.android.support:multidex:1.0.2'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$rootProject.ext.kotlinVersion"
compile "com.google.firebase:firebase-core:$playLibVersion"
compile "com.google.firebase:firebase-crash:$playLibVersion"
compile "com.google.android.gms:play-services-gcm:$playLibVersion"
debugCompile "com.facebook.stetho:stetho:$stethoVersion"
debugCompile "com.facebook.stetho:stetho-okhttp3:$stethoOkhttp3Version"
debugCompile "com.uphyca:stetho_realm:$stethoRealmVersion"
compile "com.trello.rxlifecycle2:rxlifecycle:$rxlifecycleVersion"
compile "com.trello.rxlifecycle2:rxlifecycle-android:$rxlifecycleVersion"
compile "com.trello.rxlifecycle2:rxlifecycle-components:$rxlifecycleVersion"
......@@ -138,23 +135,16 @@ dependencies {
compile('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
transitive = true;
}
debugCompile "com.facebook.stetho:stetho:$stethoVersion"
debugCompile "com.facebook.stetho:stetho-okhttp3:$stethoOkhttp3Version"
debugCompile "com.uphyca:stetho_realm:$stethoRealmVersion"
debugCompile "com.tspoon.traceur:traceur:1.0.1"
compile 'com.aurelhubert:ahbottomnavigation:2.0.6'
compile('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.10.6@aar') {
transitive = true
}
compile 'com.github.JakeWharton:ViewPagerIndicator:2.4.1@aar'
compile 'com.jakewharton:butterknife:8.6.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'
compile 'com.jakewharton.timber:timber:4.5.1'
compile 'com.github.matrixxun:MaterialBadgeTextView:c5a27e8243'
compile 'com.github.chrisbanes:PhotoView:2.0.0'
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.3'
testCompile "org.jetbrains.kotlin:kotlin-test:$rootProject.ext.kotlinVersion"
testCompile "org.jetbrains.kotlin:kotlin-test-junit:$rootProject.ext.kotlinVersion"
testCompile "org.jetbrains.kotlin:kotlin-reflect:$rootProject.ext.kotlinVersion"
testCompile "com.nhaarman:mockito-kotlin:1.1.0"
testCompile 'org.amshove.kluent:kluent:1.14'
testCompile "org.jetbrains.kotlin:kotlin-reflect:$rootProject.ext.kotlinVersion"
}
apply plugin: 'com.google.gms.google-services'
package chat.rocket.android;
import android.os.StrictMode;
import com.facebook.stetho.Stetho;
import com.tspoon.traceur.Traceur;
import com.uphyca.stetho_realm.RealmInspectorModulesProvider;
......
......@@ -5,8 +5,8 @@ import chat.rocket.android.RocketChatCache
import chat.rocket.android.api.rest.CookieInterceptor
import chat.rocket.android.api.rest.DefaultCookieProvider
import com.facebook.stetho.okhttp3.StethoInterceptor
import java.util.concurrent.TimeUnit
import okhttp3.OkHttpClient
import java.util.concurrent.TimeUnit
object OkHttpHelper {
......
......@@ -4,48 +4,65 @@ import android.os.Build;
import android.support.multidex.MultiDexApplication;
import android.support.v7.app.AppCompatDelegate;
import chat.rocket.android.helper.OkHttpHelper;
import com.crashlytics.android.Crashlytics;
import chat.rocket.android_ddp.DDPClient;
import io.fabric.sdk.android.Fabric;
import java.util.List;
import chat.rocket.persistence.realm.RealmStore;
import java.util.concurrent.TimeoutException;
import chat.rocket.android.helper.OkHttpHelper;
import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.core.models.ServerInfo;
import chat.rocket.android.widget.RocketChatWidgets;
import chat.rocket.android_ddp.DDPClient;
import chat.rocket.core.models.ServerInfo;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.RocketChatPersistenceRealm;
import io.fabric.sdk.android.Fabric;
import io.reactivex.exceptions.UndeliverableException;
import io.reactivex.plugins.RxJavaPlugins;
/**
* Customized Application-class for Rocket.Chat
*/
public class RocketChatApplication extends MultiDexApplication {
private static RocketChatApplication instance;
private static RocketChatApplication instance;
public static RocketChatApplication getInstance() {
return instance;
}
public static RocketChatApplication getInstance() {
return instance;
}
@Override
public void onCreate() {
super.onCreate();
DDPClient.initialize(OkHttpHelper.INSTANCE.getClientForWebSocket());
Fabric.with(this, new Crashlytics());
@Override
public void onCreate() {
super.onCreate();
DDPClient.initialize(OkHttpHelper.INSTANCE.getClientForWebSocket());
Fabric.with(this, new Crashlytics());
RocketChatPersistenceRealm.init(this);
RocketChatPersistenceRealm.init(this);
List<ServerInfo> serverInfoList = ConnectivityManager.getInstance(this).getServerList();
for (ServerInfo serverInfo : serverInfoList) {
RealmStore.put(serverInfo.getHostname());
}
List<ServerInfo> serverInfoList = ConnectivityManager.getInstance(this).getServerList();
for (ServerInfo serverInfo : serverInfoList) {
RealmStore.put(serverInfo.getHostname());
}
RocketChatWidgets.initialize(this, OkHttpHelper.INSTANCE.getClientForDownloadFile(this));
RocketChatWidgets.initialize(this, OkHttpHelper.INSTANCE.getClientForDownloadFile(this));
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
RxJavaPlugins.setErrorHandler(e -> {
if (e instanceof UndeliverableException) {
e = e.getCause();
}
if (e instanceof TimeoutException) {
// Some work timed-out after a server change is most probable.
return;
}
instance = this;
}
Thread.currentThread().getUncaughtExceptionHandler()
.uncaughtException(Thread.currentThread(), e);
});
instance = this;
}
}
\ No newline at end of file
......@@ -17,7 +17,6 @@ import java.util.UUID;
import chat.rocket.android.helper.Logger;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.log.RCLog;
import chat.rocket.android.push.PushManager;
import chat.rocket.core.utils.Pair;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
......
......@@ -8,8 +8,8 @@ import android.support.v4.app.Fragment;
import chat.rocket.android.R;
import chat.rocket.android.fragment.server_config.LoginFragment;
import chat.rocket.android.fragment.server_config.RetryLoginFragment;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.persistence.realm.repositories.RealmSessionRepository;
/**
......
......@@ -2,14 +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.helper.Logger;
import chat.rocket.android.service.ConnectivityManagerApi;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.interactors.SessionInteractor;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
public class LoginPresenter extends BasePresenter<LoginContract.View>
implements LoginContract.Presenter {
......
......@@ -28,7 +28,6 @@ import chat.rocket.core.models.Session;
import chat.rocket.core.models.User;
import chat.rocket.core.repositories.PublicSettingRepository;
import chat.rocket.core.utils.Pair;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
......@@ -220,7 +219,7 @@ public class MainPresenter extends BasePresenter<MainContract.View>
}
private void subscribeToNetworkChanges() {
Disposable disposable = RxJavaInterop.toV2Flowable(connectivityManagerApi.getServerConnectivityAsObservable())
Disposable disposable = connectivityManagerApi.getServerConnectivityAsObservable()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
connectivity -> {
......
......@@ -5,6 +5,7 @@ import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import chat.rocket.android.R
import chat.rocket.android.fragment.chatroom.list.RoomListFragment
import chat.rocket.core.models.Room
import kotlinx.android.synthetic.main.activity_room.*
class RoomActivity : AppCompatActivity() {
......@@ -20,7 +21,7 @@ class RoomActivity : AppCompatActivity() {
val extras = intent.extras
val roomListFragment = RoomListFragment.newInstance(extras.getInt("actionId"),
extras.getString("roomId"),
extras.getString("roomType"),
extras.getString("roomType", Room.TYPE_GROUP),
extras.getString("hostname"),
extras.getString("token"),
extras.getString("userId"))
......
package chat.rocket.android.api.rest;
import java.io.IOException;
import chat.rocket.android.helper.TextUtils;
import okhttp3.Interceptor;
import okhttp3.Request;
......
package chat.rocket.android.api.rest;
import chat.rocket.android.RocketChatCache;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.models.internal.RealmSession;
public class DefaultCookieProvider implements CookieProvider {
......
......@@ -2,12 +2,13 @@ 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;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
......
package chat.rocket.android.api.rest;
import io.reactivex.Flowable;
import org.json.JSONObject;
import io.reactivex.Flowable;
public interface ServerPolicyApi {
String SECURE_PROTOCOL = "https://";
......
......@@ -6,6 +6,7 @@ import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.trello.rxlifecycle2.components.support.RxFragment;
/**
......
......@@ -7,6 +7,7 @@ import android.support.constraint.ConstraintLayout;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.widget.TextView;
import chat.rocket.android.BuildConfig;
import chat.rocket.android.LaunchUtil;
import chat.rocket.android.R;
......
package chat.rocket.android.fragment.add_server;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.helper.Logger;
import chat.rocket.android.helper.OkHttpHelper;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import chat.rocket.android.RocketChatCache;
import chat.rocket.android.api.rest.DefaultServerPolicyApi;
import chat.rocket.android.api.rest.ServerPolicyApi;
import chat.rocket.android.helper.Logger;
import chat.rocket.android.helper.OkHttpHelper;
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 io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
public class InputHostnamePresenter extends BasePresenter<InputHostnameContract.View> implements InputHostnameContract.Presenter {
private final RocketChatCache rocketChatCache;
......
......@@ -10,11 +10,6 @@ import android.support.v4.util.Pair;
import android.view.View;
import android.widget.TextView;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.R;
import chat.rocket.android.RocketChatCache;
......@@ -34,6 +29,10 @@ import chat.rocket.persistence.realm.repositories.RealmPublicSettingRepository;
import chat.rocket.persistence.realm.repositories.RealmRoomRepository;
import chat.rocket.persistence.realm.repositories.RealmRoomRoleRepository;
import chat.rocket.persistence.realm.repositories.RealmUserRepository;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
public class MessageOptionsDialogFragment extends BottomSheetDialogFragment {
......
......@@ -47,20 +47,23 @@ class RoomListFragment : Fragment(), RoomListContract.View {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activity.title = ""
actionId = arguments.getInt("actionId")
roomId = arguments.getString("roomId")
roomType = arguments.getString("roomType")
hostname = arguments.getString("hostname")
token = arguments.getString("token")
userId = arguments.getString("userId")
activity?.title = ""
val args = arguments
args?.let {
actionId = args.getInt("actionId")
roomId = args.getString("roomId")
roomType = args.getString("roomType")
hostname = args.getString("hostname")
token = args.getString("token")
userId = args.getString("userId")
}
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater?.inflate(R.layout.fragment_room_list, container, false)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_room_list, container, false)
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter = RoomListPresenter(context, this)
presenter = RoomListPresenter(context!!, this)
}
override fun onResume() {
......@@ -114,9 +117,9 @@ class RoomListFragment : Fragment(), RoomListContract.View {
}
override fun showPinnedMessages(dataSet: ArrayList<Message>, total: String) {
activity.title = getString(R.string.fragment_room_list_pinned_message_title, total)
activity?.title = getString(R.string.fragment_room_list_pinned_message_title, total)
if (recyclerView.adapter == null) {
recyclerView.adapter = RoomMessagesAdapter(dataSet, hostname, context)
recyclerView.adapter = RoomMessagesAdapter(dataSet, hostname, context!!)
val linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recyclerView.layoutManager = linearLayoutManager
if (dataSet.size >= 50) {
......@@ -132,9 +135,9 @@ class RoomListFragment : Fragment(), RoomListContract.View {
}
override fun showFavoriteMessages(dataSet: ArrayList<Message>, total: String) {
activity.title = getString(R.string.fragment_room_list_favorite_message_title, total)
activity?.title = getString(R.string.fragment_room_list_favorite_message_title, total)
if (recyclerView.adapter == null) {
recyclerView.adapter = RoomMessagesAdapter(dataSet, hostname, context)
recyclerView.adapter = RoomMessagesAdapter(dataSet, hostname, context!!)
val linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recyclerView.layoutManager = linearLayoutManager
if (dataSet.size >= 50) {
......@@ -150,7 +153,7 @@ class RoomListFragment : Fragment(), RoomListContract.View {
}
override fun showFileList(dataSet: ArrayList<Attachment>, total: String) {
activity.title = getString(R.string.fragment_room_list_file_list_title, total)
activity?.title = getString(R.string.fragment_room_list_file_list_title, total)
if (recyclerView.adapter == null) {
recyclerView.adapter = RoomFileListAdapter(dataSet)
val linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
......@@ -168,9 +171,9 @@ class RoomListFragment : Fragment(), RoomListContract.View {
}
override fun showMemberList(dataSet: ArrayList<User>, total: String) {
activity.title = getString(R.string.fragment_room_list_member_list_title, total)
activity?.title = getString(R.string.fragment_room_list_member_list_title, total)
if (recyclerView.adapter == null) {
recyclerView.adapter = RoomMemberListAdapter(dataSet, hostname, context)
recyclerView.adapter = RoomMemberListAdapter(dataSet, hostname, context!!)
val linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recyclerView.layoutManager = linearLayoutManager
if (dataSet.size >= 50) {
......
package chat.rocket.android.fragment.oauth;
import io.reactivex.android.schedulers.AndroidSchedulers;
import org.json.JSONObject;
import chat.rocket.android.BackgroundLooper;
......@@ -10,6 +9,7 @@ import chat.rocket.android.helper.Logger;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.repositories.LoginServiceConfigurationRepository;
import io.reactivex.android.schedulers.AndroidSchedulers;
public class OAuthPresenter extends BasePresenter<OAuthContract.View>
implements OAuthContract.Presenter {
......
package chat.rocket.android.fragment.server_config;
import java.util.List;
import chat.rocket.android.shared.BaseContract;
import chat.rocket.core.models.LoginServiceConfiguration;
......
......@@ -11,6 +11,7 @@ import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
import chat.rocket.android.R;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.layouthelper.oauth.OAuthProviderInfo;
......
......@@ -3,7 +3,6 @@ package chat.rocket.android.fragment.server_config;
import android.support.annotation.NonNull;
import com.hadisatrio.optional.Optional;
import io.reactivex.android.schedulers.AndroidSchedulers;
import bolts.Task;
import chat.rocket.android.BackgroundLooper;
......@@ -16,6 +15,7 @@ import chat.rocket.core.PublicSettingsConstants;
import chat.rocket.core.models.PublicSetting;
import chat.rocket.core.repositories.LoginServiceConfigurationRepository;
import chat.rocket.core.repositories.PublicSettingRepository;
import io.reactivex.android.schedulers.AndroidSchedulers;
public class LoginPresenter extends BasePresenter<LoginContract.View>
implements LoginContract.Presenter {
......
......@@ -3,7 +3,6 @@ package chat.rocket.android.fragment.server_config;
import android.support.annotation.NonNull;
import com.hadisatrio.optional.Optional;
import io.reactivex.android.schedulers.AndroidSchedulers;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.api.MethodCallHelper;
......@@ -12,6 +11,7 @@ import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.core.models.Session;
import io.reactivex.android.schedulers.AndroidSchedulers;
public class RetryLoginPresenter extends BasePresenter<RetryLoginContract.View>
implements RetryLoginContract.Presenter {
......
......@@ -2,13 +2,14 @@ package chat.rocket.android.fragment.sidebar;
import android.support.annotation.NonNull;
import bolts.Continuation;
import chat.rocket.core.models.RoomSidebar;
import io.reactivex.Flowable;
import java.util.List;
import bolts.Continuation;
import chat.rocket.android.shared.BaseContract;
import chat.rocket.core.models.RoomSidebar;
import chat.rocket.core.models.Spotlight;
import chat.rocket.core.models.User;
import io.reactivex.Flowable;
public interface SidebarMainContract {
......
......@@ -151,6 +151,7 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
adapter.setOnItemClickListener(new RoomListAdapter.OnItemClickListener() {
@Override
public void onItemClick(RoomSidebar roomSidebar) {
searchView.setQuery(null, false);
searchView.clearFocus();
presenter.onRoomSelected(roomSidebar);
}
......
......@@ -5,11 +5,9 @@ import android.os.Bundle;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;
import com.hadisatrio.optional.Optional;
import com.jakewharton.rxbinding2.widget.RxTextView;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.realm.Case;
import bolts.Task;
import chat.rocket.android.BackgroundLooper;
......@@ -20,11 +18,14 @@ import chat.rocket.android.helper.Logger;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.sidebar.dialog.SuggestUserAdapter;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.RealmAutoCompleteAdapter;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.repositories.RealmServerInfoRepository;
import chat.rocket.persistence.realm.repositories.RealmSessionRepository;
import chat.rocket.persistence.realm.repositories.RealmUserRepository;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.realm.Case;
/**
* add Direct RealmMessage.
......
package chat.rocket.android.helper;
import com.hadisatrio.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import chat.rocket.android.fragment.chatroom.RocketChatAbsoluteUrl;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.core.repositories.ServerInfoRepository;
import chat.rocket.core.repositories.UserRepository;
import io.reactivex.Flowable;
import io.reactivex.Single;
public class AbsoluteUrlHelper {
......
......@@ -6,9 +6,11 @@ import android.text.format.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import chat.rocket.android.log.RCLog;
/**
......@@ -55,7 +57,7 @@ public class DateTime {
case DAY:
return DAY_FORMAT.format(cal.getTime());
case DATE:
return DATE_FORMAT.format(cal.getTime());
return getDateFormat(cal.getTime());
case TIME:
return TIME_FORMAT.format(cal.getTime());
case DATE_TIME:
......@@ -80,6 +82,22 @@ public class DateTime {
}
}
private static String getDateFormat(Date dateTime) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(dateTime);
Calendar today = Calendar.getInstance();
Calendar yesterday = Calendar.getInstance();
yesterday.add(Calendar.DATE, -1);
if (calendar.get(Calendar.YEAR) == today.get(Calendar.YEAR) && calendar.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR)) {
return "Today";
} else if (calendar.get(Calendar.YEAR) == yesterday.get(Calendar.YEAR) && calendar.get(Calendar.DAY_OF_YEAR) == yesterday.get(Calendar.DAY_OF_YEAR)) {
return "Yesterday";
} else {
return DATE_FORMAT.format(dateTime);
}
}
/**
* parse datetime string to ms.
*/
......
......@@ -8,16 +8,18 @@ import android.os.ParcelFileDescriptor;
import android.provider.OpenableColumns;
import android.support.annotation.Nullable;
import android.webkit.MimeTypeMap;
import org.json.JSONObject;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.UUID;
import chat.rocket.android.log.RCLog;
import chat.rocket.core.SyncState;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.models.ddp.RealmPublicSetting;
import chat.rocket.persistence.realm.models.internal.FileUploading;
import chat.rocket.persistence.realm.RealmHelper;
/**
* utility class for uploading file.
......
package chat.rocket.android.helper;
import io.realm.Realm;
import io.realm.RealmResults;
import java.util.List;
import chat.rocket.persistence.realm.models.ddp.RealmPublicSetting;
import chat.rocket.core.PublicSettingsConstants;
import chat.rocket.persistence.realm.models.ddp.RealmPublicSetting;
import io.realm.Realm;
import io.realm.RealmResults;
/**
* utility class for getting value comprehensibly from public settings list.
......
package chat.rocket.android.helper;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.functions.Func1;
import io.reactivex.Flowable;
import io.reactivex.functions.Function;
/**
* Rx operator and so on.
*/
public class RxHelper {
public static Func1<Observable<? extends Throwable>, Observable<?>> exponentialBackoff(
public static Function<Flowable<? extends Throwable>, Flowable<?>> exponentialBackoff(
int maxRetryCount, long base, TimeUnit unit) {
// ref: https://github.com/ReactiveX/RxJava/blob/a8ba158839b67246a742b6f1531995ffd7545c08/src/main/java/io/reactivex/Observable.java#L9601
return attempts -> attempts
.zipWith(Observable.range(0, maxRetryCount), (error, retryCount) -> retryCount)
.flatMap(retryCount -> Observable.timer(base * (long) Math.pow(2, retryCount), unit));
.zipWith(Flowable.range(0, maxRetryCount), (error, retryCount) -> retryCount)
.flatMap(retryCount -> Flowable.timer(base * (long) Math.pow(2, retryCount), unit));
}
}
......@@ -2,9 +2,8 @@ package chat.rocket.android.helper;
import android.support.annotation.NonNull;
import io.reactivex.Flowable;
import chat.rocket.android.api.rest.ServerPolicyApi;
import io.reactivex.Flowable;
public class ServerPolicyApiValidationHelper {
......
......@@ -2,9 +2,10 @@ package chat.rocket.android.helper;
import android.support.annotation.NonNull;
import io.reactivex.Flowable;
import org.json.JSONObject;
import io.reactivex.Flowable;
public class ServerPolicyHelper {
private static final String DEFAULT_HOST = ".rocket.chat";
......
......@@ -4,6 +4,7 @@ import android.support.annotation.Nullable;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import chat.rocket.android.R;
import chat.rocket.android.helper.DateTime;
import chat.rocket.android.helper.TextUtils;
......
......@@ -7,6 +7,7 @@ import android.view.View;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import chat.rocket.android.R;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.ExtModelListAdapter;
......
package chat.rocket.android.layouthelper.chatroom;
import android.view.View;
import chat.rocket.android.R;
import chat.rocket.android.renderer.MessageRenderer;
import chat.rocket.android.widget.AbsoluteUrl;
......
......@@ -7,10 +7,13 @@ import android.view.ViewGroup
import android.widget.TextView
import chat.rocket.android.R
import chat.rocket.android.helper.DateTime
import chat.rocket.android.helper.Logger
import chat.rocket.android.log.RCLog
import chat.rocket.android.widget.message.RocketChatMessageAttachmentsLayout
import chat.rocket.core.models.Attachment
import kotlinx.android.synthetic.main.day.view.*
import kotlinx.android.synthetic.main.item_room_file.view.*
import java.lang.IllegalArgumentException
import java.sql.Timestamp
/**
......@@ -26,8 +29,16 @@ class RoomFileListAdapter(private var dataSet: List<Attachment>) : RecyclerView.
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val attachment = dataSet[position]
holder.newDay.text = DateTime.fromEpocMs(Timestamp.valueOf(attachment.timestamp).time, DateTime.Format.DATE)
holder.attachment.appendAttachmentView(attachment, true, false)
val timestamp: Timestamp?
try {
timestamp = Timestamp.valueOf(attachment.timestamp)
// If we don't have a timestamp we can parse let's be safe and stop here.
holder.newDay.text = DateTime.fromEpocMs(timestamp.time, DateTime.Format.DATE)
holder.attachment.appendAttachmentView(attachment, true, false)
} catch (e: IllegalArgumentException) {
RCLog.e(e)
Logger.report(e)
}
}
override fun getItemCount(): Int = dataSet.size
......
......@@ -7,13 +7,14 @@ import android.view.View;
import android.view.ViewGroup;
import java.util.List;
import chat.rocket.android.R;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.renderer.UserRenderer;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.core.models.User;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.android.renderer.UserRenderer;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
/**
* RecyclerView adapter for UsersOfRooms.
......
......@@ -2,9 +2,10 @@ package chat.rocket.android.layouthelper.chatroom.roomlist;
import android.support.annotation.NonNull;
import chat.rocket.core.models.RoomSidebar;
import java.util.List;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.RoomSidebar;
public class ChannelRoomListHeader implements RoomListHeader {
......
......@@ -2,9 +2,10 @@ package chat.rocket.android.layouthelper.chatroom.roomlist;
import android.support.annotation.NonNull;
import chat.rocket.core.models.RoomSidebar;
import java.util.List;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.RoomSidebar;
public class DirectMessageRoomListHeader implements RoomListHeader {
......
......@@ -2,9 +2,10 @@ package chat.rocket.android.layouthelper.chatroom.roomlist;
import android.support.annotation.NonNull;
import chat.rocket.core.models.RoomSidebar;
import java.util.List;
import chat.rocket.core.models.RoomSidebar;
public class FavoriteRoomListHeader implements RoomListHeader {
private final String title;
......
......@@ -5,14 +5,15 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import chat.rocket.core.models.RoomSidebar;
import chat.rocket.core.models.Spotlight;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import chat.rocket.android.R;
import chat.rocket.android.widget.internal.RoomListItemView;
import chat.rocket.core.models.RoomSidebar;
import chat.rocket.core.models.Spotlight;
public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
......
......@@ -2,9 +2,10 @@ package chat.rocket.android.layouthelper.chatroom.roomlist;
import android.support.annotation.NonNull;
import chat.rocket.core.models.RoomSidebar;
import java.util.List;
import chat.rocket.core.models.RoomSidebar;
public interface RoomListHeader {
String getTitle();
......
......@@ -2,9 +2,10 @@ package chat.rocket.android.layouthelper.chatroom.roomlist;
import android.support.annotation.NonNull;
import chat.rocket.core.models.RoomSidebar;
import java.util.List;
import chat.rocket.core.models.RoomSidebar;
public class UnreadRoomListHeader implements RoomListHeader {
private final String title;
......
......@@ -3,6 +3,7 @@ package chat.rocket.android.layouthelper.oauth;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import chat.rocket.android.R;
import chat.rocket.android.fragment.oauth.AbstractOAuthFragment;
import chat.rocket.android.fragment.oauth.FacebookOAuthFragment;
......
......@@ -5,11 +5,12 @@ import android.view.View;
import java.util.Iterator;
import java.util.List;
import chat.rocket.android.R;
import chat.rocket.android.renderer.UserRenderer;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.RealmAutoCompleteAdapter;
import chat.rocket.android.renderer.UserRenderer;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
/**
* adapter to suggest user names.
......
......@@ -5,8 +5,8 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.support.v4.app.RemoteInput;
import android.util.Log;
import chat.rocket.android.push.gcm.GCMIntentService;
......
......@@ -95,6 +95,9 @@ object PushManager {
hostToPushMessageList.remove(host)
}
/**
* Remove a notification solely by it's unique id.
*/
fun clearNotificationsByNotificationId(notificationId: Int) {
if (hostToPushMessageList.isNotEmpty()) {
for (entry in hostToPushMessageList.entries) {
......@@ -105,7 +108,13 @@ object PushManager {
}
}
fun clearNotificationsByHostAndNotificationId(host: String, notificationId: Int) {
/**
* Clear notifications by the host they belong to and its unique id.
*/
fun clearNotificationsByHostAndNotificationId(host: String?, notificationId: Int?) {
if (host == null || notificationId == null) {
return
}
if (hostToPushMessageList.isNotEmpty()) {
val notifications = hostToPushMessageList[host]
notifications?.let {
......
......@@ -3,13 +3,14 @@ package chat.rocket.android.push.gcm;
import com.google.android.gms.iid.InstanceIDListenerService;
import java.util.List;
import chat.rocket.android.helper.GcmPushSettingHelper;
import chat.rocket.persistence.realm.models.ddp.RealmPublicSetting;
import chat.rocket.persistence.realm.models.internal.GcmPushRegistration;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.core.models.ServerInfo;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmPublicSetting;
import chat.rocket.persistence.realm.models.internal.GcmPushRegistration;
public class GcmInstanceIDListenerService extends InstanceIDListenerService {
......
......@@ -4,9 +4,10 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.util.List;
import chat.rocket.core.models.ServerInfo;
import rx.Observable;
import rx.Single;
import io.reactivex.Observable;
import io.reactivex.Single;
/**
* interfaces used for Activity/Fragment and other UI-related logic.
......
package chat.rocket.android.service;
import java.util.List;
import chat.rocket.core.models.ServerInfo;
/**
......
package chat.rocket.android.service;
import rx.Single;
import io.reactivex.Single;
public interface ConnectivityServiceInterface {
Single<Boolean> ensureConnectionToServer(String hostname);
......
......@@ -20,10 +20,10 @@ import chat.rocket.android_ddp.DDPClient;
import chat.rocket.core.models.ServerInfo;
import chat.rocket.persistence.realm.models.RealmBasedServerInfo;
import hugo.weaving.DebugLog;
import rx.Observable;
import rx.Single;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;
/**
* Connectivity management implementation.
......@@ -155,7 +155,7 @@ import rx.subjects.PublishSubject;
@Override
public Observable<ServerConnectivity> getServerConnectivityAsObservable() {
return Observable.concat(Observable.from(getCurrentConnectivityList()), connectivitySubject);
return Observable.concat(Observable.fromIterable(getCurrentConnectivityList()), connectivitySubject);
}
@Override
......@@ -176,11 +176,6 @@ import rx.subjects.PublishSubject;
.flatMap(_val -> connectToServerIfNeeded(hostname, forceConnect));
}
// if (connectivity == ServerConnectivity.STATE_CONNECTING) {
// return waitForConnected(hostname)
// .doOnError(error -> notifyConnectionLost(hostname, REASON_NETWORK_ERROR));
// }
if (connectivity == ServerConnectivity.STATE_DISCONNECTED) {
notifyConnecting(hostname);
}
......@@ -219,7 +214,7 @@ import rx.subjects.PublishSubject;
.filter(state ->
state == ServerConnectivity.STATE_CONNECTED
|| state == ServerConnectivity.STATE_DISCONNECTED)
.first()
.firstElement()
.toSingle()
.flatMap(state ->
state == ServerConnectivity.STATE_CONNECTED
......@@ -233,7 +228,7 @@ import rx.subjects.PublishSubject;
.filter(serverConnectivity -> hostname.equals(serverConnectivity.hostname))
.map(serverConnectivity -> serverConnectivity.state)
.filter(state -> state == ServerConnectivity.STATE_DISCONNECTED)
.first()
.firstElement()
.toSingle()
.map(state -> true);
}
......
......@@ -15,8 +15,8 @@ import chat.rocket.android.helper.Logger;
import chat.rocket.android.log.RCLog;
import chat.rocket.persistence.realm.RealmStore;
import hugo.weaving.DebugLog;
import rx.Observable;
import rx.Single;
import io.reactivex.Observable;
import io.reactivex.Single;
/**
* Background service for Rocket.Chat.Application class.
......@@ -72,7 +72,6 @@ public class RocketChatService extends Service implements ConnectivityServiceInt
.doOnError(err -> {
err.printStackTrace();
currentWebSocketThread = null;
// connectivityManager.notifyConnectionLost(hostname, ConnectivityManagerInternal.REASON_NETWORK_ERROR);
})
.flatMap(webSocketThreads -> webSocketThreads.keepAlive());
}
......@@ -93,7 +92,7 @@ public class RocketChatService extends Service implements ConnectivityServiceInt
RealmStore.sStore.remove(hostname);
});
} else {
return Observable.timer(1, TimeUnit.SECONDS).toSingle()
return Observable.timer(1, TimeUnit.SECONDS).singleOrError()
.flatMap(_val -> disconnectFromServer(hostname));
}
});
......
......@@ -41,11 +41,10 @@ import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import hugo.weaving.DebugLog;
import io.reactivex.Completable;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.disposables.CompositeDisposable;
import rx.Completable;
import rx.Single;
import rx.subscriptions.CompositeSubscription;
/**
* Thread for handling WebSocket connection.
......@@ -74,7 +73,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
private final ConnectivityManagerInternal connectivityManager;
private final ArrayList<Registrable> listeners = new ArrayList<>();
private final CompositeDisposable hearbeatDisposable = new CompositeDisposable();
private final CompositeSubscription reconnectSubscription = new CompositeSubscription();
private final CompositeDisposable reconnectSubscription = new CompositeDisposable();
private boolean listenersRegistered;
private static class KeepAliveTimer {
......@@ -110,13 +109,14 @@ public class RocketChatWebSocketThread extends HandlerThread {
*/
@DebugLog
public static Single<RocketChatWebSocketThread> getStarted(Context appContext, String hostname) {
return Single.<RocketChatWebSocketThread>fromEmitter(objectSingleEmitter -> {
return Single.<RocketChatWebSocketThread>fromPublisher(objectSingleEmitter -> {
new RocketChatWebSocketThread(appContext, hostname) {
@Override
protected void onLooperPrepared() {
try {
super.onLooperPrepared();
objectSingleEmitter.onSuccess(this);
objectSingleEmitter.onNext(this);
objectSingleEmitter.onComplete();
} catch (Exception exception) {
objectSingleEmitter.onError(exception);
}
......@@ -151,14 +151,15 @@ public class RocketChatWebSocketThread extends HandlerThread {
@DebugLog
public Single<Boolean> terminate() {
if (isAlive()) {
return Single.fromEmitter(emitter -> {
return Single.fromPublisher(emitter -> {
new Handler(getLooper()).post(() -> {
RCLog.d("thread %s: terminated()", Thread.currentThread().getId());
unregisterListenersAndClose();
connectivityManager.notifyConnectionLost(hostname,
DDPClient.REASON_CLOSED_BY_USER);
RocketChatWebSocketThread.super.quit();
emitter.onSuccess(true);
emitter.onNext(true);
emitter.onComplete();
});
});
} else {
......@@ -198,7 +199,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
}
keepAliveTimer.update();
return Single.fromEmitter(emitter -> {
return Single.fromPublisher(emitter -> {
new Thread() {
@Override
public void run() {
......@@ -211,7 +212,8 @@ public class RocketChatWebSocketThread extends HandlerThread {
emitter.onError(error);
} else {
keepAliveTimer.update();
emitter.onSuccess(true);
emitter.onNext(true);
emitter.onComplete();
}
return null;
});
......@@ -251,10 +253,11 @@ public class RocketChatWebSocketThread extends HandlerThread {
private Single<Boolean> connectDDPClient() {
return prepareDDPClient()
.flatMap(_val -> Single.fromEmitter(emitter -> {
.flatMap(_val -> Single.fromPublisher(emitter -> {
ServerInfo info = connectivityManager.getServerInfoForHost(hostname);
if (info == null) {
emitter.onSuccess(false);
emitter.onNext(false);
emitter.onComplete();
return;
}
RCLog.d("DDPClient#connect");
......@@ -292,7 +295,8 @@ public class RocketChatWebSocketThread extends HandlerThread {
if (task.isFaulted()) {
emitter.onError(task.getError());
} else {
emitter.onSuccess(true);
emitter.onNext(true);
emitter.onComplete();
}
return null;
});
......@@ -301,13 +305,11 @@ public class RocketChatWebSocketThread extends HandlerThread {
private void reconnect() {
// if we are already trying to reconnect then return.
if (reconnectSubscription.hasSubscriptions()) {
if (reconnectSubscription.size() > 0) {
return;
}
forceInvalidateTokens();
connectivityManager.notifyConnecting(hostname);
// Needed to use subscriptions because of legacy code.
// TODO: Should update to RxJava 2
reconnectSubscription.add(
connectWithExponentialBackoff()
.subscribe(
......@@ -326,9 +328,9 @@ public class RocketChatWebSocketThread extends HandlerThread {
);
}
private void logErrorAndUnsubscribe(CompositeSubscription subscriptions, Throwable err) {
private void logErrorAndUnsubscribe(CompositeDisposable disposables, Throwable err) {
RCLog.e(err);
subscriptions.clear();
disposables.clear();
}
private Single<Boolean> connectWithExponentialBackoff() {
......@@ -338,11 +340,12 @@ public class RocketChatWebSocketThread extends HandlerThread {
@DebugLog
private Single<Boolean> connect() {
return connectDDPClient()
.flatMap(_val -> Single.fromEmitter(emitter -> {
.flatMap(_val -> Single.fromPublisher(emitter -> {
fetchPublicSettings();
fetchPermissions();
registerListeners();
emitter.onSuccess(true);
emitter.onNext(true);
emitter.onComplete();
}));
}
......@@ -376,9 +379,9 @@ public class RocketChatWebSocketThread extends HandlerThread {
if (sessions != null && sessions.size() > 0) {
// if we have a session try to resume it. At this point we're probably recovering from
// a disconnection state
final CompositeSubscription subscriptions = new CompositeSubscription();
final CompositeDisposable disposables = new CompositeDisposable();
MethodCallHelper methodCall = new MethodCallHelper(realmHelper);
subscriptions.add(
disposables.add(
Completable.defer(() -> {
Task<Void> result = methodCall.loginWithToken(sessions.get(0).getToken());
if (result.isFaulted()) {
......@@ -390,9 +393,9 @@ public class RocketChatWebSocketThread extends HandlerThread {
.subscribe(
() -> {
createObserversAndRegister();
subscriptions.clear();
disposables.clear();
},
error -> logErrorAndUnsubscribe(subscriptions, error)
error -> logErrorAndUnsubscribe(disposables, error)
)
);
} else {
......
package chat.rocket.android.service.observer;
import android.content.Context;
import java.util.List;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.helper.LogIfError;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import io.realm.Realm;
import io.realm.RealmResults;
public class TokenLoginObserver extends AbstractModelObserver<RealmSession> {
private final MethodCallHelper methodCall;
public TokenLoginObserver(Context context, String hostname,
RealmHelper realmHelper) {
super(context, hostname, realmHelper);
methodCall = new MethodCallHelper(realmHelper);
}
@Override
public RealmResults<RealmSession> queryItems(Realm realm) {
return realm.where(RealmSession.class)
.isNotNull(RealmSession.TOKEN)
.equalTo(RealmSession.TOKEN_VERIFIED, false)
.isNull(RealmSession.ERROR)
.findAll();
}
@Override
public void onUpdateResults(List<RealmSession> results) {
if (results.isEmpty()) {
return;
}
RealmSession session = results.get(0);
methodCall.loginWithToken(session.getToken()).continueWith(new LogIfError());
}
}
......@@ -67,7 +67,7 @@ class PushManagerTest {
on { getColor(any()) } doReturn 0
on { getIdentifier(
anyString(), anyString(), any()) } doReturn R.drawable.notification_background
anyString(), anyString(), any()) } doReturn R.drawable.notification_icon_background
on { getConfiguration() } doReturn RuntimeEnvironment.application.resources.configuration
}
......
......@@ -12,11 +12,12 @@ buildscript {
google()
jcenter()
maven { url 'https://maven.fabric.io/public' }
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.51"
classpath 'io.realm:realm-gradle-plugin:3.0.0'
classpath 'io.realm:realm-gradle-plugin:4.2.0-SNAPSHOT'
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'
......@@ -35,6 +36,7 @@ allprojects {
maven { url 'http://dl.bintray.com/amulyakhare/maven' } //for TextDrawable.
maven { url "https://clojars.org/repo/" } //for icepick.
maven { url 'https://jitpack.io' } //for widget-fontawesome.
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local' } //for widget-fontawesome.
}
}
......
ext {
preDexLibs = "true" != System.getenv("CI")
supportLibraryVersion = "25.4.0"
supportLibraryVersion = "27.0.1"
constraintLayoutVersion = "1.0.2"
kotlinVersion = "1.1.51"
okHttpVersion = "3.9.0"
......@@ -9,16 +9,18 @@ ext {
supportDependencies = [
designSupportLibrary: "com.android.support:design:${supportLibraryVersion}",
annotation : "com.android.support:support-annotations:${supportLibraryVersion}",
constrainLayout : "com.android.support.constraint:constraint-layout:${constraintLayoutVersion}",
kotlin : "org.jetbrains.kotlin:kotlin-stdlib-jre7:${kotlinVersion}",
constraintLayout : "com.android.support.constraint:constraint-layout:${constraintLayoutVersion}",
cardView : "com.android.support:cardview-v7:${supportLibraryVersion}",
supportV13 : "com.android.support:support-v13:${supportLibraryVersion}",
multidex : "com.android.support:multidex:1.0.2"
]
extraDependencies = [
okHTTP : "com.squareup.okhttp3:okhttp:${okHttpVersion}",
rxJava : "io.reactivex.rxjava2:rxjava:2.1.0",
boltTask : "com.parse.bolts:bolts-tasks:1.4.0",
rxAndroid : "io.reactivex.rxjava2:rxandroid:2.0.1",
textDrawable : "com.github.rocketchat:textdrawable:1.0.2"
textDrawable : "com.github.rocketchat:textdrawable:1.0.2",
optional : "com.hadisatrio:Optional:v1.0.1"
]
rxbindingDependencies = [
rxBinding : "com.jakewharton.rxbinding2:rxbinding:${rxbindingVersion}",
......
......@@ -36,13 +36,11 @@ dependencies {
compile extraDependencies.boltTask
compile supportDependencies.annotation
compile supportDependencies.designSupportLibrary
compile supportDependencies.kotlin
compile extraDependencies.rxAndroid
provided extraDependencies.optional
testCompile "org.jetbrains.kotlin:kotlin-test:$rootProject.ext.kotlinVersion"
testCompile "org.jetbrains.kotlin:kotlin-test-junit:$rootProject.ext.kotlinVersion"
testCompile 'org.json:json:20170516'
testCompile 'org.skyscreamer:jsonassert:1.5.0'
compile 'com.github.akarnokd:rxjava2-interop:0.10.0'
provided 'com.hadisatrio:Optional:v1.0.1'
testCompile 'junit:junit:4.12'
}
package chat.rocket.persistence.realm;
import io.realm.DynamicRealm;
import io.realm.FieldAttribute;
import io.realm.RealmMigration;
import io.realm.RealmObjectSchema;
import io.realm.RealmSchema;
import chat.rocket.persistence.realm.models.ddp.RealmMessage;
import chat.rocket.persistence.realm.models.ddp.RealmPermission;
import chat.rocket.persistence.realm.models.ddp.RealmRole;
import chat.rocket.persistence.realm.models.ddp.RealmRoomRole;
import chat.rocket.persistence.realm.models.ddp.RealmSpotlightRoom;
import chat.rocket.persistence.realm.models.ddp.RealmSpotlightUser;
import io.realm.DynamicRealm;
import io.realm.FieldAttribute;
import io.realm.RealmMigration;
import io.realm.RealmObjectSchema;
import io.realm.RealmSchema;
public class Migration implements RealmMigration {
@Override
......
......@@ -8,13 +8,14 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.RealmResults;
import java.util.Collections;
import java.util.List;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.RealmResults;
/**
* ListAdapter for AutoCompleteTextView.
*/
......
......@@ -3,18 +3,23 @@ package chat.rocket.persistence.realm;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Looper;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmObject;
import io.realm.RealmQuery;
import io.realm.RealmResults;
import org.json.JSONException;
import java.util.Collections;
import java.util.List;
import bolts.Task;
import bolts.TaskCompletionSource;
import chat.rocket.android.log.RCLog;
import io.reactivex.Flowable;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmModel;
import io.realm.RealmObject;
import io.realm.RealmQuery;
import io.realm.RealmResults;
import io.realm.log.RealmLog;
@SuppressLint("NewApi")
public class RealmHelper {
......@@ -164,6 +169,25 @@ public class RealmHelper {
return constructor.getNewInstance(context).initializeWith(this, filter);
}
public static <T extends RealmModel> Flowable<T> copyToRealmOrUpdate(Realm realm, T objectToCopy) {
return Flowable.defer(() -> {
realm.beginTransaction();
try {
T object = realm.copyToRealmOrUpdate(objectToCopy);
realm.commitTransaction();
return Flowable.just(object);
} catch (Throwable e) {
if (realm.isInTransaction()) {
realm.cancelTransaction();
} else {
RealmLog.warn("Could not cancel transaction, not currently in a transaction.");
}
throw e;
}
});
}
public interface Transaction<T> {
T execute(Realm realm) throws JSONException;
}
......
package chat.rocket.persistence.realm;
import java.util.List;
import io.realm.Realm;
import io.realm.RealmChangeListener;
import io.realm.RealmObject;
import io.realm.RealmResults;
import java.util.List;
public class RealmListObserver<T extends RealmObject> extends AbstractRealmResultsObserver<T> {
private final Query<T> query;
private OnUpdateListener<T> onUpdateListener;
......
package chat.rocket.persistence.realm;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import java.util.HashMap;
import chat.rocket.persistence.realm.modules.RocketChatLibraryModule;
import chat.rocket.persistence.realm.modules.RocketChatServerModule;
import io.realm.Realm;
import io.realm.RealmConfiguration;
public class RealmStore {
public static HashMap<String, RealmConfiguration> sStore = new HashMap<>();
......
package chat.rocket.persistence.realm;
import android.content.Context;
import io.realm.Realm;
import io.realm.RealmConfiguration;
......
......@@ -2,17 +2,18 @@ package chat.rocket.persistence.realm.models;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import chat.rocket.core.models.ServerInfo;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmStore;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
/**
* Backend implementation to store ServerInfo.
......@@ -41,7 +42,7 @@ public class RealmBasedServerInfo extends RealmObject {
.build();
}
public static Realm getRealm() {
public static Realm getServerRealm() {
return RealmStore.getRealm(DB_NAME);
}
......
package chat.rocket.persistence.realm.models.ddp;
import chat.rocket.core.models.Email;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import chat.rocket.core.models.Email;
/**
* Login-RealmUser's email.
*/
......
package chat.rocket.persistence.realm.models.ddp;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
......@@ -10,6 +8,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import chat.rocket.core.JsonConstants;
import chat.rocket.core.SyncState;
import chat.rocket.core.models.Attachment;
......@@ -21,6 +20,8 @@ import chat.rocket.core.models.WebContent;
import chat.rocket.core.models.WebContentHeaders;
import chat.rocket.core.models.WebContentMeta;
import chat.rocket.core.models.WebContentParsedUrl;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
/**
* RealmMessage.
......@@ -191,7 +192,7 @@ public class RealmMessage extends RealmObject {
.setRoomId(rid)
.setSyncState(syncstate)
.setTimestamp(ts)
.setMessage(msg)
.setMessage(msg == null ? "" : msg)
.setUser(u != null ? u.asUser() : null)
.setGroupable(groupable)
.setAlias(alias)
......
package chat.rocket.persistence.realm.models.ddp;
import chat.rocket.core.models.LoginServiceConfiguration;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import chat.rocket.core.models.LoginServiceConfiguration;
/**
* subscription model for "meteor_accounts_loginServiceConfiguration".
*/
......
package chat.rocket.persistence.realm.models.ddp;
import io.realm.RealmList;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import chat.rocket.core.models.Permission;
import chat.rocket.core.models.Role;
import io.realm.RealmList;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
public class RealmPermission extends RealmObject {
......
package chat.rocket.persistence.realm.models.ddp;
import chat.rocket.core.models.Preferences;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import chat.rocket.core.models.Preferences;
@SuppressWarnings({"PMD.ShortVariable"})
public class RealmPreferences extends RealmObject {
......
package chat.rocket.persistence.realm.models.ddp;
import android.support.annotation.Nullable;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import org.json.JSONException;
import org.json.JSONObject;
import chat.rocket.core.JsonConstants;
import chat.rocket.core.models.PublicSetting;
import chat.rocket.persistence.realm.RealmHelper;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
/**
* public setting model.
......
package chat.rocket.persistence.realm.models.ddp;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import org.json.JSONException;
import org.json.JSONObject;
import chat.rocket.core.models.Role;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
public class RealmRole extends RealmObject {
......
package chat.rocket.persistence.realm.models.ddp;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import org.json.JSONException;
import org.json.JSONObject;
import chat.rocket.core.JsonConstants;
import chat.rocket.core.models.Room;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
/**
* Chat Room(Subscription).
......@@ -142,7 +142,7 @@ public class RealmRoom extends RealmObject {
return Room.builder()
.setId(_id)
.setRoomId(rid)
.setName(name)
.setName(name == null ? "" : name)
.setType(t)
.setOpen(open)
.setAlert(alert)
......
package chat.rocket.persistence.realm.models.ddp;
import io.realm.RealmList;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import chat.rocket.core.models.Role;
import chat.rocket.core.models.RoomRole;
import io.realm.RealmList;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
public class RealmRoomRole extends RealmObject {
......
package chat.rocket.persistence.realm.models.ddp;
import chat.rocket.core.models.Settings;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import chat.rocket.core.models.Settings;
@SuppressWarnings({"PMD.ShortVariable"})
public class RealmSettings extends RealmObject {
......
package chat.rocket.persistence.realm.models.ddp;
import chat.rocket.core.models.SpotlightRoom;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import chat.rocket.core.models.SpotlightRoom;
public class RealmSpotlightRoom extends RealmObject {
public interface Columns {
......
package chat.rocket.persistence.realm.models.ddp;
import chat.rocket.core.models.SpotlightUser;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import chat.rocket.core.models.SpotlightUser;
public class RealmSpotlightUser extends RealmObject {
public interface Columns {
......
package chat.rocket.persistence.realm.models.internal;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.RealmQuery;
import io.realm.annotations.PrimaryKey;
import org.json.JSONException;
import org.json.JSONObject;
import chat.rocket.core.SyncState;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.RealmQuery;
import io.realm.annotations.PrimaryKey;
/**
* just stores gcm registration status.
......
package chat.rocket.persistence.realm.models.internal;
import chat.rocket.core.models.RoomHistoryState;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import chat.rocket.core.models.RoomHistoryState;
/**
* Load messages in the room.
*/
......
package chat.rocket.persistence.realm.models.internal;
import android.text.TextUtils;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.UUID;
import bolts.Task;
import bolts.TaskCompletionSource;
import chat.rocket.android.log.RCLog;
......@@ -14,6 +14,8 @@ import chat.rocket.core.SyncState;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmObjectObserver;
import chat.rocket.persistence.realm.helpers.LogcatIfError;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
public class MethodCall extends RealmObject {
......
package chat.rocket.persistence.realm.models.internal;
import android.text.TextUtils;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.RealmQuery;
import io.realm.annotations.PrimaryKey;
import org.json.JSONObject;
import chat.rocket.core.models.Session;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.helpers.LogcatIfError;
import hugo.weaving.DebugLog;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.RealmQuery;
import io.realm.annotations.PrimaryKey;
/**
* Login session info.
......
package chat.rocket.persistence.realm.modules;
import io.realm.annotations.RealmModule;
import chat.rocket.persistence.realm.models.RealmBasedServerInfo;
import io.realm.annotations.RealmModule;
@RealmModule(library = true, classes = {RealmBasedServerInfo.class})
public class RocketChatServerModule {
......
......@@ -2,19 +2,20 @@ package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import com.hadisatrio.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.RealmResults;
import java.util.ArrayList;
import java.util.List;
import chat.rocket.core.models.LoginServiceConfiguration;
import chat.rocket.core.repositories.LoginServiceConfigurationRepository;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmMeteorLoginServiceConfiguration;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.RealmResults;
public class RealmLoginServiceConfigurationRepository extends RealmRepository
implements LoginServiceConfigurationRepository {
......@@ -34,11 +35,10 @@ public class RealmLoginServiceConfigurationRepository extends RealmRepository
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(
pair.first.where(RealmMeteorLoginServiceConfiguration.class)
return pair.first.where(RealmMeteorLoginServiceConfiguration.class)
.equalTo(RealmMeteorLoginServiceConfiguration.SERVICE, serviceName)
.findAll()
.<RealmResults<RealmMeteorLoginServiceConfiguration>>asObservable());
.<RealmResults<RealmMeteorLoginServiceConfiguration>>asFlowable();
},
pair -> close(pair.first, pair.second)
)
......@@ -57,10 +57,9 @@ public class RealmLoginServiceConfigurationRepository extends RealmRepository
return Flowable.empty();
}
return RxJavaInterop
.toV2Flowable(pair.first.where(RealmMeteorLoginServiceConfiguration.class)
return pair.first.where(RealmMeteorLoginServiceConfiguration.class)
.findAll()
.asObservable());
.asFlowable();
},
pair -> close(pair.first, pair.second)
)
......
......@@ -5,25 +5,24 @@ import android.support.v4.util.Pair;
import com.hadisatrio.optional.Optional;
import chat.rocket.core.SyncState;
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;
import java.util.ArrayList;
import java.util.List;
import chat.rocket.core.SyncState;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.User;
import chat.rocket.core.repositories.MessageRepository;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmMessage;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
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;
public class RealmMessageRepository extends RealmRepository implements MessageRepository {
......@@ -42,11 +41,11 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(
return
pair.first.where(RealmMessage.class)
.equalTo(RealmMessage.ID, messageId)
.findAll()
.<RealmResults<RealmMessage>>asObservable());
.<RealmResults<RealmMessage>>asFlowable();
},
pair -> close(pair.first, pair.second)
)
......@@ -91,16 +90,12 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe
}
realmMessage.setUser(realmUser);
realm.beginTransaction();
final RealmMessage messageToSave = realmMessage;
return RxJavaInterop.toV2Flowable(realm.copyToRealmOrUpdate(realmMessage)
.asObservable())
return RealmHelper.copyToRealmOrUpdate(realm, messageToSave)
.filter(it -> it.isLoaded() && it.isValid())
.firstElement()
.doOnSuccess(it -> realm.commitTransaction())
.doOnError(throwable -> realm.cancelTransaction())
.first(new RealmMessage())
.doOnEvent((realmObject, throwable) -> close(realm, looper))
.toSingle()
.map(realmObject -> true);
});
}
......@@ -117,10 +112,10 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe
realm.beginTransaction();
return RxJavaInterop.toV2Flowable(realm.where(RealmMessage.class)
return realm.where(RealmMessage.class)
.equalTo(RealmMessage.ID, message.getId())
.findAll()
.<RealmResults<RealmMessage>>asObservable())
.<RealmResults<RealmMessage>>asFlowable()
.filter(realmObject -> realmObject.isLoaded() && realmObject.isValid())
.firstElement()
.toSingle()
......@@ -145,13 +140,13 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(pair.first.where(RealmMessage.class)
return pair.first.where(RealmMessage.class)
.notEqualTo(RealmMessage.SYNC_STATE, SyncState.DELETE_NOT_SYNCED)
.notEqualTo(RealmMessage.SYNC_STATE, SyncState.DELETING)
.equalTo(RealmMessage.ROOM_ID, room.getRoomId())
.isNotNull(RealmMessage.USER)
.findAllSorted(RealmMessage.TIMESTAMP, Sort.DESCENDING)
.asObservable());
.asFlowable();
},
pair -> close(pair.first, pair.second)
)
......@@ -170,12 +165,12 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(pair.first.where(RealmMessage.class)
return pair.first.where(RealmMessage.class)
.equalTo(RealmMessage.ROOM_ID, room.getId())
.greaterThanOrEqualTo(RealmMessage.TIMESTAMP, room.getLastSeen())
.notEqualTo(RealmMessage.USER_ID, user.getId())
.findAll()
.asObservable());
.asFlowable();
},
pair -> close(pair.first, pair.second)
)
......
......@@ -2,17 +2,17 @@ package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import com.hadisatrio.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.RealmResults;
import chat.rocket.core.models.Permission;
import chat.rocket.core.repositories.PermissionRepository;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmPermission;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.RealmResults;
public class RealmPermissionRepository extends RealmRepository implements PermissionRepository {
......@@ -30,11 +30,10 @@ public class RealmPermissionRepository extends RealmRepository implements Permis
if (pair.first == null) {
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(
pair.first.where(RealmPermission.class)
return pair.first.where(RealmPermission.class)
.equalTo(RealmPermission.Columns.ID, id)
.findAll()
.<RealmResults<RealmPermission>>asObservable());
.<RealmResults<RealmPermission>>asFlowable();
},
pair -> close(pair.first, pair.second)
)
......
......@@ -2,17 +2,17 @@ package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import com.hadisatrio.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.RealmResults;
import chat.rocket.core.models.PublicSetting;
import chat.rocket.core.repositories.PublicSettingRepository;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmPublicSetting;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.RealmResults;
public class RealmPublicSettingRepository extends RealmRepository
implements PublicSettingRepository {
......@@ -31,11 +31,10 @@ public class RealmPublicSettingRepository extends RealmRepository
if (pair.first == null) {
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(
pair.first.where(RealmPublicSetting.class)
return pair.first.where(RealmPublicSetting.class)
.equalTo(RealmPublicSetting.ID, id)
.findAll()
.<RealmResults<RealmPublicSetting>>asObservable());
.<RealmResults<RealmPublicSetting>>asFlowable();
},
pair -> close(pair.first, pair.second)
)
......
......@@ -2,12 +2,13 @@ package chat.rocket.persistence.realm.repositories;
import android.os.Handler;
import android.os.Looper;
import java.util.List;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.RealmResults;
import java.util.List;
public class RealmRepository {
protected void close(Realm realm, Looper looper) {
......
......@@ -2,25 +2,27 @@ package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import com.hadisatrio.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.Case;
import io.realm.Realm;
import io.realm.RealmResults;
import io.realm.Sort;
import java.util.ArrayList;
import java.util.List;
import chat.rocket.core.SortDirection;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.RoomHistoryState;
import chat.rocket.core.repositories.RoomRepository;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmRoom;
import chat.rocket.persistence.realm.models.internal.LoadMessageProcedure;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.Case;
import io.realm.Realm;
import io.realm.RealmResults;
import io.realm.Sort;
public class RealmRoomRepository extends RealmRepository implements RoomRepository {
......@@ -39,10 +41,9 @@ public class RealmRoomRepository extends RealmRepository implements RoomReposito
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(
pair.first.where(RealmRoom.class)
return pair.first.where(RealmRoom.class)
.findAll()
.asObservable());
.asFlowable();
},
pair -> close(pair.first, pair.second)
)
......@@ -69,13 +70,11 @@ public class RealmRoomRepository extends RealmRepository implements RoomReposito
return Flowable.just(Optional.<RealmRoom>absent());
}
return RxJavaInterop.toV2Flowable(
realmRoom
.<RealmRoom>asObservable()
return realmRoom.<RealmRoom>asFlowable()
.filter(
roomSubscription -> roomSubscription.isLoaded()
&& roomSubscription.isValid())
.map(Optional::of));
.map(Optional::of);
},
pair -> close(pair.first, pair.second)
)
......@@ -106,12 +105,10 @@ public class RealmRoomRepository extends RealmRepository implements RoomReposito
return Flowable.just(Optional.<LoadMessageProcedure>absent());
}
return RxJavaInterop.toV2Flowable(
messageProcedure
.<LoadMessageProcedure>asObservable()
return messageProcedure.<LoadMessageProcedure>asFlowable()
.filter(loadMessageProcedure -> loadMessageProcedure.isLoaded()
&& loadMessageProcedure.isValid())
.map(Optional::of));
.map(Optional::of);
},
pair -> close(pair.first, pair.second)
)
......@@ -142,14 +139,9 @@ public class RealmRoomRepository extends RealmRepository implements RoomReposito
loadMessage.setHasNext(!roomHistoryState.isComplete());
loadMessage.setTimestamp(roomHistoryState.getTimestamp());
realm.beginTransaction();
return RxJavaInterop.toV2Flowable(realm.copyToRealmOrUpdate(loadMessage)
.asObservable())
return RealmHelper.copyToRealmOrUpdate(realm, loadMessage)
.filter(realmObject -> realmObject.isLoaded() && realmObject.isValid())
.firstElement()
.doOnSuccess(it -> realm.commitTransaction())
.doOnError(throwable -> realm.cancelTransaction())
.doOnEvent((realmObject, throwable) -> close(realm, looper))
.toSingle()
.map(realmObject -> true);
......@@ -164,8 +156,7 @@ public class RealmRoomRepository extends RealmRepository implements RoomReposito
if (pair.first == null) {
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(
pair.first.where(RealmRoom.class)
return pair.first.where(RealmRoom.class)
.like(RealmRoom.NAME, "*" + name + "*", Case.INSENSITIVE)
.beginGroup()
.equalTo(RealmRoom.TYPE, RealmRoom.TYPE_CHANNEL)
......@@ -174,7 +165,7 @@ public class RealmRoomRepository extends RealmRepository implements RoomReposito
.endGroup()
.findAllSorted(RealmRoom.NAME,
direction.equals(SortDirection.ASC) ? Sort.ASCENDING : Sort.DESCENDING)
.asObservable());
.asFlowable();
},
pair -> close(pair.first, pair.second)
)
......@@ -192,15 +183,14 @@ public class RealmRoomRepository extends RealmRepository implements RoomReposito
if (pair.first == null) {
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(
pair.first.where(RealmRoom.class)
return pair.first.where(RealmRoom.class)
.beginGroup()
.equalTo(RealmRoom.TYPE, RealmRoom.TYPE_CHANNEL)
.or()
.equalTo(RealmRoom.TYPE, RealmRoom.TYPE_PRIVATE)
.endGroup()
.findAllSorted(RealmRoom.LAST_SEEN, Sort.ASCENDING)
.asObservable());
.asFlowable();
},
pair -> close(pair.first, pair.second)
)
......
......@@ -2,11 +2,8 @@ package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import com.hadisatrio.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.RealmResults;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.RoomRole;
......@@ -15,7 +12,10 @@ import chat.rocket.core.repositories.RoomRoleRepository;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmRoomRole;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.RealmResults;
public class RealmRoomRoleRepository extends RealmRepository implements RoomRoleRepository {
......@@ -33,12 +33,11 @@ public class RealmRoomRoleRepository extends RealmRepository implements RoomRole
if (pair.first == null) {
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(
pair.first.where(RealmRoomRole.class)
return pair.first.where(RealmRoomRole.class)
.equalTo(RealmRoomRole.Columns.ROOM_ID, room.getId())
.equalTo(RealmRoomRole.Columns.USER + "." + RealmUser.ID, user.getId())
.findAll()
.<RealmResults<RealmRoomRole>>asObservable());
.<RealmResults<RealmRoomRole>>asFlowable();
},
pair -> close(pair.first, pair.second)
)
......
......@@ -2,21 +2,21 @@ package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import com.hadisatrio.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import chat.rocket.core.models.ServerInfo;
import chat.rocket.core.repositories.ServerInfoRepository;
import chat.rocket.persistence.realm.models.RealmBasedServerInfo;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
public class RealmServerInfoRepository extends RealmRepository implements ServerInfoRepository {
@Override
public Flowable<Optional<ServerInfo>> getByHostname(String hostname) {
return Flowable.defer(() -> Flowable.using(
() -> new Pair<>(RealmBasedServerInfo.getRealm(), Looper.myLooper()),
() -> new Pair<>(RealmBasedServerInfo.getServerRealm(), Looper.myLooper()),
pair -> {
RealmBasedServerInfo info = pair.first.where(RealmBasedServerInfo.class)
.equalTo(RealmBasedServerInfo.ColumnName.HOSTNAME, hostname)
......@@ -26,10 +26,9 @@ public class RealmServerInfoRepository extends RealmRepository implements Server
return Flowable.just(Optional.<RealmBasedServerInfo>absent());
}
return RxJavaInterop.toV2Flowable(info
.<RealmBasedServerInfo>asObservable()
return info.<RealmBasedServerInfo>asFlowable()
.filter(it -> it.isLoaded() && it.isValid())
.map(Optional::of));
.map(Optional::of);
},
pair -> close(pair.first, pair.second)
)
......
......@@ -2,17 +2,17 @@ package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import com.hadisatrio.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 hu.akarnokd.rxjava.interop.RxJavaInterop;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.Realm;
public class RealmSessionRepository extends RealmRepository implements SessionRepository {
......@@ -31,11 +31,10 @@ public class RealmSessionRepository extends RealmRepository implements SessionRe
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(
pair.first.where(RealmSession.class)
return pair.first.where(RealmSession.class)
.equalTo(RealmSession.ID, id)
.findAll()
.<RealmSession>asObservable());
.<RealmSession>asFlowable();
},
pair -> close(pair.first, pair.second)
)
......@@ -76,8 +75,8 @@ public class RealmSessionRepository extends RealmRepository implements SessionRe
realm.beginTransaction();
return RxJavaInterop.toV2Flowable(realm.copyToRealmOrUpdate(realmSession)
.asObservable())
return realm.copyToRealmOrUpdate(realmSession)
.asFlowable()
.filter(it -> it != null && it.isLoaded() && it.isValid())
.firstElement()
.doOnSuccess(it -> realm.commitTransaction())
......
package chat.rocket.persistence.realm.repositories
import android.os.Looper
import android.support.v4.util.Pair
import chat.rocket.core.models.Spotlight
import chat.rocket.core.repositories.SpotlightRepository
import chat.rocket.persistence.realm.RealmStore
import chat.rocket.persistence.realm.models.ddp.RealmSpotlight
import chat.rocket.persistence.realm.models.ddp.RealmSpotlight.Columns
import hu.akarnokd.rxjava.interop.RxJavaInterop
import io.reactivex.Flowable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.realm.Realm
import io.realm.RealmResults
import io.realm.Sort
import java.util.ArrayList
import java.util.*
class RealmSpotlightRepository(private val hostname: String) : RealmRepository(), SpotlightRepository {
......@@ -25,9 +23,9 @@ class RealmSpotlightRepository(private val hostname: String) : RealmRepository()
return@using Flowable.empty()
}
return@using RxJavaInterop.toV2Flowable<RealmResults<RealmSpotlight>>(pair.first.where(RealmSpotlight::class.java)
return@using pair.first.where(RealmSpotlight::class.java)
.findAllSorted(Columns.TYPE, Sort.DESCENDING)
.asObservable())
.asFlowable()
}) { pair -> close(pair.first, pair.second) }
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()!!))
.filter { realmSpotlightResults -> realmSpotlightResults.isLoaded && realmSpotlightResults.isValid }
......
......@@ -2,20 +2,20 @@ package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.Case;
import io.realm.Sort;
import java.util.ArrayList;
import java.util.List;
import chat.rocket.core.SortDirection;
import chat.rocket.core.models.SpotlightRoom;
import chat.rocket.core.repositories.SpotlightRoomRepository;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmRoom;
import chat.rocket.persistence.realm.models.ddp.RealmSpotlightRoom;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.realm.Case;
import io.realm.Sort;
public class RealmSpotlightRoomRepository extends RealmRepository implements SpotlightRoomRepository {
......@@ -34,8 +34,7 @@ public class RealmSpotlightRoomRepository extends RealmRepository implements Spo
return Flowable.empty();
}
return RxJavaInterop.toV2Flowable(
pair.first.where(RealmSpotlightRoom.class)
return pair.first.where(RealmSpotlightRoom.class)
.like(RealmSpotlightRoom.Columns.NAME, "*" + name + "*", Case.INSENSITIVE)
.beginGroup()
.equalTo(RealmSpotlightRoom.Columns.TYPE, RealmRoom.TYPE_CHANNEL)
......@@ -43,7 +42,7 @@ public class RealmSpotlightRoomRepository extends RealmRepository implements Spo
.equalTo(RealmSpotlightRoom.Columns.TYPE, RealmRoom.TYPE_PRIVATE)
.endGroup()
.findAllSorted(RealmSpotlightRoom.Columns.NAME, direction.equals(SortDirection.ASC) ? Sort.ASCENDING : Sort.DESCENDING)
.asObservable());
.asFlowable();
},
pair -> close(pair.first, pair.second)
)
......
This diff is collapsed.
This diff is collapsed.
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