Commit 83acd2ad authored by Leonardo Aramaki's avatar Leonardo Aramaki

Merge branch 'develop' into fix/remove-keepalive-task

parents 0921ac06 9cf18839
......@@ -2,7 +2,7 @@ package chat.rocket.android.api;
import android.content.Context;
import android.util.Patterns;
import chat.rocket.persistence.realm.models.ddp.RealmSpotlight;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
......@@ -463,15 +463,53 @@ public class MethodCallHelper {
}
public Task<Void> searchSpotlightUsers(String term) {
return searchSpotlight(
RealmSpotlightUser.class, "users", term
);
return searchSpotlight(RealmSpotlightUser.class, "users", term);
}
public Task<Void> searchSpotlightRooms(String term) {
return searchSpotlight(
RealmSpotlightRoom.class, "rooms", term
);
return searchSpotlight(RealmSpotlightRoom.class, "rooms", term);
}
public Task<Void> searchSpotlight(String term) {
return call("spotlight", TIMEOUT_MS, () ->
new JSONArray()
.put(term)
.put(JSONObject.NULL)
.put(new JSONObject().put("rooms", true).put("users", true))
).onSuccessTask(CONVERT_TO_JSON_OBJECT)
.onSuccessTask(task -> {
String jsonString = null;
final JSONObject result = task.getResult();
JSONArray roomJsonArray = (JSONArray) result.get("rooms");
if (roomJsonArray.length() > 0) {
jsonString = roomJsonArray.toString();
}
JSONArray userJsonArray = (JSONArray) result.get("users");
int usersTotal = userJsonArray.length();
if (usersTotal > 0) {
for (int i = 0; i < usersTotal; ++i) {
RealmSpotlight.Companion.customizeUserJSONObject(userJsonArray.getJSONObject(i));
}
if (jsonString == null) {
jsonString = userJsonArray.toString();
} else {
jsonString = jsonString.replace("]", "") + "," + userJsonArray.toString().replace("[", "");
}
}
if (jsonString != null) {
String jsonStringResults = jsonString;
realmHelper.executeTransaction(realm -> {
realm.delete(RealmSpotlight.class);
realm.createOrUpdateAllFromJson(RealmSpotlight.class, jsonStringResults);
return null;
});
}
return null;
});
}
private Task<Void> searchSpotlight(Class clazz, String key, String term) {
......
......@@ -2,11 +2,11 @@ package chat.rocket.android.fragment.sidebar;
import android.support.annotation.NonNull;
import io.reactivex.Flowable;
import java.util.List;
import chat.rocket.android.fragment.chatroom.RocketChatAbsoluteUrl;
import chat.rocket.android.shared.BaseContract;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.SpotlightRoom;
import chat.rocket.core.models.Spotlight;
import chat.rocket.core.models.User;
public interface SidebarMainContract {
......@@ -19,14 +19,16 @@ public interface SidebarMainContract {
void showRoomList(@NonNull List<Room> roomList);
void show(User user, RocketChatAbsoluteUrl absoluteUrl);
void show(User user);
}
interface Presenter extends BaseContract.Presenter<View> {
void onRoomSelected(Room room);
void onSpotlightRoomSelected(SpotlightRoom spotlightRoom);
void onSpotlightSelected(Spotlight spotlight);
Flowable<List<Spotlight>> searchSpotlight(String term);
void onUserOnline();
......
......@@ -16,12 +16,10 @@ import chat.rocket.android.R;
import chat.rocket.android.RocketChatCache;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.fragment.AbstractFragment;
import chat.rocket.android.fragment.chatroom.RocketChatAbsoluteUrl;
import chat.rocket.android.fragment.sidebar.dialog.AddChannelDialogFragment;
import chat.rocket.android.fragment.sidebar.dialog.AddDirectMessageDialogFragment;
import chat.rocket.android.helper.AbsoluteUrlHelper;
import chat.rocket.android.helper.Logger;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.chatroom.roomlist.ChannelRoomListHeader;
import chat.rocket.android.layouthelper.chatroom.roomlist.DirectMessageRoomListHeader;
import chat.rocket.android.layouthelper.chatroom.roomlist.FavoriteRoomListHeader;
......@@ -29,16 +27,15 @@ import chat.rocket.android.layouthelper.chatroom.roomlist.RoomListAdapter;
import chat.rocket.android.layouthelper.chatroom.roomlist.RoomListHeader;
import chat.rocket.android.layouthelper.chatroom.roomlist.UnreadRoomListHeader;
import chat.rocket.android.renderer.UserRenderer;
import chat.rocket.core.SortDirection;
import chat.rocket.core.interactors.RoomInteractor;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.SpotlightRoom;
import chat.rocket.core.models.Spotlight;
import chat.rocket.core.models.User;
import chat.rocket.persistence.realm.repositories.RealmRoomRepository;
import chat.rocket.persistence.realm.repositories.RealmServerInfoRepository;
import chat.rocket.persistence.realm.repositories.RealmSessionRepository;
import chat.rocket.persistence.realm.repositories.RealmSpotlightRoomRepository;
import chat.rocket.persistence.realm.repositories.RealmSpotlightRepository;
import chat.rocket.persistence.realm.repositories.RealmUserRepository;
import com.jakewharton.rxbinding2.support.v7.widget.RxSearchView;
import com.jakewharton.rxbinding2.widget.RxCompoundButton;
......@@ -50,21 +47,13 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
public class SidebarMainFragment extends AbstractFragment implements SidebarMainContract.View {
private static final String HOSTNAME = "hostname";
private SidebarMainContract.Presenter presenter;
private RoomListAdapter adapter;
private String hostname;
private MethodCallHelper methodCallHelper;
private RealmSpotlightRoomRepository realmSpotlightRoomRepository;
private SearchView searchView;
private String hostname;
private static final String HOSTNAME = "hostname";
public SidebarMainFragment() {
}
public SidebarMainFragment() {}
/**
* create SidebarMainFragment with hostname.
......@@ -83,12 +72,7 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
hostname = args == null ? null : args.getString(HOSTNAME);
methodCallHelper = new MethodCallHelper(getContext(), hostname);
realmSpotlightRoomRepository = new RealmSpotlightRoomRepository(hostname);
hostname = getArguments().getString(HOSTNAME);
RealmUserRepository userRepository = new RealmUserRepository(hostname);
AbsoluteUrlHelper absoluteUrlHelper = new AbsoluteUrlHelper(
......@@ -104,7 +88,8 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
userRepository,
new RocketChatCache(getContext()),
absoluteUrlHelper,
TextUtils.isEmpty(hostname) ? null : new MethodCallHelper(getContext(), hostname)
new MethodCallHelper(getContext(), hostname),
new RealmSpotlightRepository(hostname)
);
}
......@@ -133,6 +118,8 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
setupLogoutButton();
setupVersionInfo();
searchView = rootView.findViewById(R.id.search);
adapter = new RoomListAdapter();
adapter.setOnItemClickListener(new RoomListAdapter.OnItemClickListener() {
@Override
......@@ -142,57 +129,39 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
}
@Override
public void onItemClick(SpotlightRoom spotlightRoom) {
public void onItemClick(Spotlight spotlight) {
searchView.setQuery(null, false);
searchView.clearFocus();
methodCallHelper.joinRoom(spotlightRoom.getId())
.onSuccessTask(task -> {
presenter.onSpotlightRoomSelected(spotlightRoom);
return null;
});
presenter.onSpotlightSelected(spotlight);
}
});
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.room_list_container);
recyclerView.setLayoutManager(
new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
RecyclerView recyclerView = rootView.findViewById(R.id.room_list_container);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
recyclerView.setAdapter(adapter);
searchView = (SearchView) rootView.findViewById(R.id.search);
RxSearchView.queryTextChanges(searchView)
.compose(bindToLifecycle())
.debounce(300, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.switchMap(it -> {
if (it.length() == 0) {
.switchMap(charSequence -> {
if (charSequence.length() == 0) {
adapter.setMode(RoomListAdapter.MODE_ROOM);
return Observable.just(Collections.<SpotlightRoom>emptyList());
return Observable.just(Collections.<Spotlight>emptyList());
} else {
adapter.setMode(RoomListAdapter.MODE_SPOTLIGHT);
return presenter.searchSpotlight(charSequence.toString()).toObservable();
}
adapter.setMode(RoomListAdapter.MODE_SPOTLIGHT_ROOM);
final String queryString = it.toString();
methodCallHelper.searchSpotlightRooms(queryString);
return realmSpotlightRoomRepository.getSuggestionsFor(queryString, SortDirection.DESC, 10)
.toObservable();
})
.subscribe(
this::showSearchSuggestions,
Logger::report
);
.subscribe(this::showSearchSuggestions, Logger::report);
}
@SuppressLint("RxLeakedSubscription")
private void setupUserActionToggle() {
final CompoundButton toggleUserAction =
((CompoundButton) rootView.findViewById(R.id.toggle_user_action));
final CompoundButton toggleUserAction = rootView.findViewById(R.id.toggle_user_action);
toggleUserAction.setFocusableInTouchMode(false);
rootView.findViewById(R.id.user_info_container)
.setOnClickListener(view -> toggleUserAction.toggle());
rootView.findViewById(R.id.user_info_container).setOnClickListener(view -> toggleUserAction.toggle());
RxCompoundButton.checkedChanges(toggleUserAction)
.compose(bindToLifecycle())
......@@ -203,6 +172,27 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
);
}
@Override
public void showScreen() {
rootView.setVisibility(View.VISIBLE);
}
@Override
public void showEmptyScreen() {
rootView.setVisibility(View.INVISIBLE);
}
@Override
public void showRoomList(@NonNull List<Room> roomList) {
adapter.setRooms(roomList);
}
@Override
public void show(User user) {
onRenderCurrentUser(user);
updateRoomListMode(user);
}
private void setupUserStatusButtons() {
rootView.findViewById(R.id.btn_status_online).setOnClickListener(view -> {
presenter.onUserOnline();
......@@ -222,8 +212,8 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
});
}
private void onRenderCurrentUser(User user, RocketChatAbsoluteUrl absoluteUrl) {
if (user != null && absoluteUrl != null) {
private void onRenderCurrentUser(User user) {
if (user != null) {
UserRenderer userRenderer = new UserRenderer(user);
userRenderer.showAvatar(rootView.findViewById(R.id.current_user_avatar), hostname);
userRenderer.showUsername(rootView.findViewById(R.id.current_user_name));
......@@ -261,22 +251,20 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
rootView.findViewById(R.id.btn_logout).setOnClickListener(view -> {
presenter.onLogout();
closeUserActionContainer();
// destroy Activity on logout to be able to recreate most of the environment
this.getActivity().finish();
});
}
private void closeUserActionContainer() {
final CompoundButton toggleUserAction =
((CompoundButton) rootView.findViewById(R.id.toggle_user_action));
final CompoundButton toggleUserAction = rootView.findViewById(R.id.toggle_user_action);
if (toggleUserAction != null && toggleUserAction.isChecked()) {
toggleUserAction.setChecked(false);
}
}
private void setupVersionInfo() {
TextView versionInfoView = (TextView) rootView.findViewById(R.id.version_info);
TextView versionInfoView = rootView.findViewById(R.id.version_info);
versionInfoView.setText(getString(R.string.version_info_text, BuildConfig.VERSION_NAME));
}
......@@ -284,28 +272,7 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
dialog.show(getFragmentManager(), "AbstractAddRoomDialogFragment");
}
@Override
public void showScreen() {
rootView.setVisibility(View.VISIBLE);
}
@Override
public void showEmptyScreen() {
rootView.setVisibility(View.INVISIBLE);
}
@Override
public void showRoomList(@NonNull List<Room> roomList) {
adapter.setRooms(roomList);
}
@Override
public void show(User user, RocketChatAbsoluteUrl absoluteUrl) {
onRenderCurrentUser(user, absoluteUrl);
updateRoomListMode(user);
}
private void showSearchSuggestions(List<SpotlightRoom> spotlightRooms) {
adapter.setSpotlightRoomList(spotlightRooms);
private void showSearchSuggestions(List<Spotlight> spotlightList) {
adapter.setSpotlightList(spotlightList);
}
}
\ No newline at end of file
......@@ -3,6 +3,8 @@ package chat.rocket.android.fragment.sidebar;
import android.support.annotation.NonNull;
import android.support.v4.util.Pair;
import chat.rocket.core.models.Spotlight;
import chat.rocket.persistence.realm.repositories.RealmSpotlightRepository;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
......@@ -17,31 +19,34 @@ import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.interactors.RoomInteractor;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.SpotlightRoom;
import chat.rocket.core.models.User;
import chat.rocket.core.repositories.UserRepository;
import java.util.List;
public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View>
implements SidebarMainContract.Presenter {
public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View> implements SidebarMainContract.Presenter {
private final String hostname;
private String userId;
private final RoomInteractor roomInteractor;
private final UserRepository userRepository;
private final RocketChatCache rocketChatCache;
private final AbsoluteUrlHelper absoluteUrlHelper;
private final MethodCallHelper methodCallHelper;
private RealmSpotlightRepository realmSpotlightRepository;
public SidebarMainPresenter(String hostname, RoomInteractor roomInteractor,
public SidebarMainPresenter(String hostname,
RoomInteractor roomInteractor,
UserRepository userRepository,
RocketChatCache rocketChatCache,
AbsoluteUrlHelper absoluteUrlHelper,
MethodCallHelper methodCallHelper) {
MethodCallHelper methodCallHelper,
RealmSpotlightRepository realmSpotlightRepository) {
this.hostname = hostname;
this.roomInteractor = roomInteractor;
this.userRepository = userRepository;
this.rocketChatCache = rocketChatCache;
this.absoluteUrlHelper = absoluteUrlHelper;
this.methodCallHelper = methodCallHelper;
this.realmSpotlightRepository = realmSpotlightRepository;
}
@Override
......@@ -65,7 +70,10 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
pair -> view.show(pair.first.orNull(), pair.second.orNull()),
pair -> {
userId = pair.first.orNull().getId();
view.show(pair.first.orNull());
},
Logger::report
);
......@@ -78,8 +86,31 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View
}
@Override
public void onSpotlightRoomSelected(SpotlightRoom spotlightRoom) {
rocketChatCache.setSelectedRoomId(spotlightRoom.getId());
public Flowable<List<Spotlight>> searchSpotlight(String term) {
methodCallHelper.searchSpotlight(term);
return realmSpotlightRepository.getSuggestionsFor(term, 10);
}
@Override
public void onSpotlightSelected(Spotlight spotlight) {
if (spotlight.getType().equals(Room.TYPE_DIRECT_MESSAGE)) {
String username = spotlight.getName();
methodCallHelper.createDirectMessage(username)
.continueWithTask(task -> {
if (task.isCompleted()) {
rocketChatCache.setSelectedRoomId(spotlight.getId() + userId);
}
return null;
});
} else {
methodCallHelper.joinRoom(spotlight.getId())
.continueWithTask(task -> {
if (task.isCompleted()) {
rocketChatCache.setSelectedRoomId(spotlight.getId());
}
return null;
});
}
}
@Override
......@@ -104,10 +135,8 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View
@Override
public void onLogout() {
if (methodCallHelper != null) {
methodCallHelper.logout().continueWith(new LogIfError());
}
}
private void subscribeToRooms() {
final Disposable subscription = roomInteractor.getOpenRooms()
......@@ -123,8 +152,6 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View
}
private void updateCurrentUserStatus(String status) {
if (methodCallHelper != null) {
methodCallHelper.setUserStatus(status).continueWith(new LogIfError());
}
}
}
\ No newline at end of file
......@@ -5,6 +5,7 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import chat.rocket.core.models.Spotlight;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
......@@ -12,18 +13,17 @@ import java.util.Map;
import chat.rocket.android.R;
import chat.rocket.android.widget.internal.RoomListItemView;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.SpotlightRoom;
public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final int MODE_ROOM = 0;
public static final int MODE_SPOTLIGHT_ROOM = 1;
public static final int MODE_SPOTLIGHT = 1;
private static final int VIEW_TYPE_HEADER = 0;
private static final int VIEW_TYPE_ROOM = 1;
private List<Room> roomList = Collections.emptyList();
private List<SpotlightRoom> spotlightRoomList = Collections.emptyList();
private List<Spotlight> spotlightList = Collections.emptyList();
private List<RoomListHeader> roomListHeaders = Collections.emptyList();
private Map<Integer, RoomListHeader> headersPosition = new HashMap<>();
......@@ -39,9 +39,9 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
@Override
public void onItemClick(SpotlightRoom spotlightRoom) {
public void onItemClick(Spotlight spotlight) {
if (externalListener != null) {
externalListener.onItemClick(spotlightRoom);
externalListener.onItemClick(spotlight);
}
}
};
......@@ -56,8 +56,8 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
updateRoomList();
}
public void setSpotlightRoomList(@NonNull List<SpotlightRoom> spotlightRoomList) {
this.spotlightRoomList = spotlightRoomList;
public void setSpotlightList(@NonNull List<Spotlight> spotlightList) {
this.spotlightList = spotlightList;
updateRoomList();
}
......@@ -66,7 +66,7 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
if (mode == MODE_ROOM) {
// clean up
spotlightRoomList.clear();
spotlightList.clear();
}
}
......@@ -96,23 +96,22 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
((RoomListItemViewHolder) holder)
.bind(roomList.get(position - getTotalHeadersBeforePosition(position)));
} else if (mode == MODE_SPOTLIGHT_ROOM) {
((RoomListItemViewHolder) holder)
.bind(spotlightRoomList.get(position));
} else if (mode == MODE_SPOTLIGHT) {
((RoomListItemViewHolder) holder).bind(spotlightList.get(position));
}
}
@Override
public int getItemCount() {
if (mode == MODE_SPOTLIGHT_ROOM) {
return spotlightRoomList.size();
if (mode == MODE_SPOTLIGHT) {
return spotlightList.size();
}
return roomList.size() + headersPosition.size();
}
@Override
public int getItemViewType(int position) {
if (mode == MODE_SPOTLIGHT_ROOM) {
if (mode == MODE_SPOTLIGHT) {
return VIEW_TYPE_ROOM;
}
......@@ -188,6 +187,6 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
public interface OnItemClickListener {
void onItemClick(Room room);
void onItemClick(SpotlightRoom spotlightRoom);
void onItemClick(Spotlight spotlight);
}
}
\ No newline at end of file
......@@ -4,7 +4,7 @@ import android.support.v7.widget.RecyclerView;
import chat.rocket.android.widget.internal.RoomListItemView;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.SpotlightRoom;
import chat.rocket.core.models.Spotlight;
public class RoomListItemViewHolder extends RecyclerView.ViewHolder {
public RoomListItemViewHolder(RoomListItemView itemView,
......@@ -17,8 +17,8 @@ public class RoomListItemViewHolder extends RecyclerView.ViewHolder {
if (tag instanceof Room) {
listener.onItemClick((Room) view.getTag());
} else if (tag instanceof SpotlightRoom) {
listener.onItemClick((SpotlightRoom) view.getTag());
} else if (tag instanceof Spotlight) {
listener.onItemClick((Spotlight) view.getTag());
}
}
});
......@@ -34,13 +34,13 @@ public class RoomListItemViewHolder extends RecyclerView.ViewHolder {
.setTag(room);
}
public void bind(SpotlightRoom spotlightRoom) {
public void bind(Spotlight spotlight) {
((RoomListItemView) itemView)
.setRoomId(spotlightRoom.getId())
.setRoomName(spotlightRoom.getName())
.setRoomType(spotlightRoom.getType())
.setRoomId(spotlight.getId())
.setRoomName(spotlight.getName())
.setRoomType(spotlight.getType())
.setAlert(false)
.setUnreadCount(0)
.setTag(spotlightRoom);
.setTag(spotlight);
}
}
......@@ -5,8 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/AppTheme.Dark"
android:visibility="invisible"
tools:visibility="visible">
tools:context="chat.rocket.android.fragment.sidebar.SidebarMainFragment">
<LinearLayout
android:id="@+id/user_info_container"
......@@ -53,7 +52,6 @@
android:id="@+id/toggle_user_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<FrameLayout
......@@ -76,7 +74,7 @@
android:id="@+id/search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:queryHint="@string/navigation_search_rooms"
app:queryHint="@string/spotlight_search"
app:iconifiedByDefault="false" />
</FrameLayout>
......
......@@ -62,7 +62,7 @@
<string name="two_factor_authentication_title">Two-factor authentication</string>
<string name="open_your_authentication_app_and_enter_the_code">Open your authentication app and enter the code</string>
<string name="two_factor_code">Two-factor code</string>
<string name="navigation_search_rooms">Search Rooms</string>
<string name="spotlight_search">Search</string>
<string name="edit_message">Edit message</string>
<string name="message_options_no_message_info">Ooops. Something\'s up!</string>
<string name="message_options_no_permissions_info">You have no permissions</string>
......
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'realm-android'
apply plugin: 'com.jakewharton.hugo'
apply plugin: 'me.tatarka.retrolambda'
......@@ -9,6 +10,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$rootProject.ext.kotlinVersion"
classpath 'io.realm:realm-gradle-plugin:2.3.2'
classpath 'me.tatarka:gradle-retrolambda:3.5.0'
classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
......@@ -36,6 +38,11 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
test.java.srcDirs += 'src/test/kotlin'
androidTest.java.srcDirs += 'src/androidTest/kotlin'
}
}
dependencies {
......@@ -46,6 +53,13 @@ dependencies {
compile "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion"
compile "com.android.support:design:$rootProject.ext.supportLibraryVersion"
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$rootProject.ext.kotlinVersion"
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 'io.reactivex.rxjava2:rxjava:2.1.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
......
package chat.rocket.persistence.realm.models.ddp
import chat.rocket.core.models.Spotlight
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import org.json.JSONObject
// This class must be annotated with open to work properly with Realm (Kotlin classes are final by default).
open class RealmSpotlight : RealmObject() {
@PrimaryKey var _id: String? = null
var name: String? = null
var t: String? = null
fun asSpotlight(): Spotlight {
return Spotlight.builder()
.setId(_id)
.setName(name)
.setType(t)
.build()
}
companion object {
fun customizeUserJSONObject(userJsonObject: JSONObject) {
userJsonObject.put(Columns.NAME, userJsonObject.get("username"))
userJsonObject.put(Columns.TYPE, "d")
userJsonObject.remove("username")
userJsonObject.remove("status")
}
}
interface Columns {
companion object {
const val ID = "_id"
const val NAME = "name"
const val TYPE = "t"
}
}
}
\ No newline at end of file
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.Case
import io.realm.Realm
import io.realm.RealmResults
import io.realm.Sort
import java.util.ArrayList
class RealmSpotlightRepository(private val hostname: String) : RealmRepository(), SpotlightRepository {
override fun getSuggestionsFor(term: String, limit: Int): Flowable<List<Spotlight>> {
return Flowable.defer { Flowable.using<RealmResults<RealmSpotlight>, Pair<Realm, Looper>>({
Pair<Realm, Looper>(RealmStore.getRealm(hostname), Looper.myLooper())
}, { pair -> RxJavaInterop.toV2Flowable<RealmResults<RealmSpotlight>>(pair.first.where(RealmSpotlight::class.java)
.findAllSorted(Columns.TYPE, Sort.DESCENDING)
.asObservable())
}) { pair -> close(pair.first, pair.second) }
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()!!))
.filter { realmSpotlightResults -> realmSpotlightResults.isLoaded && realmSpotlightResults.isValid }
.map { realmSpotlightResults -> toList(safeSubList<RealmSpotlight>(realmSpotlightResults, 0, limit)) }
}
}
private fun toList(realmSpotlightList: List<RealmSpotlight>): List<Spotlight> {
val total = realmSpotlightList.size
val spotlightList = ArrayList<Spotlight>(total)
(0..total - 1).mapTo(spotlightList) {
realmSpotlightList[it].asSpotlight()
}
return spotlightList
}
}
\ No newline at end of file
......@@ -17,8 +17,7 @@ import chat.rocket.persistence.realm.models.ddp.RealmRoom;
import chat.rocket.persistence.realm.models.ddp.RealmSpotlightRoom;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
public class RealmSpotlightRoomRepository extends RealmRepository
implements SpotlightRoomRepository {
public class RealmSpotlightRoomRepository extends RealmRepository implements SpotlightRoomRepository {
private final String hostname;
......@@ -27,8 +26,7 @@ public class RealmSpotlightRoomRepository extends RealmRepository
}
@Override
public Flowable<List<SpotlightRoom>> getSuggestionsFor(String name, SortDirection direction,
int limit) {
public Flowable<List<SpotlightRoom>> getSuggestionsFor(String name, SortDirection direction, int limit) {
return Flowable.defer(() -> Flowable.using(
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(
......@@ -39,8 +37,7 @@ public class RealmSpotlightRoomRepository extends RealmRepository
.or()
.equalTo(RealmSpotlightRoom.Columns.TYPE, RealmRoom.TYPE_PRIVATE)
.endGroup()
.findAllSorted(RealmSpotlightRoom.Columns.NAME,
direction.equals(SortDirection.ASC) ? Sort.ASCENDING : Sort.DESCENDING)
.findAllSorted(RealmSpotlightRoom.Columns.NAME, direction.equals(SortDirection.ASC) ? Sort.ASCENDING : Sort.DESCENDING)
.asObservable()),
pair -> close(pair.first, pair.second)
)
......
......@@ -16,8 +16,7 @@ import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmSpotlightUser;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
public class RealmSpotlightUserRepository extends RealmRepository
implements SpotlightUserRepository {
public class RealmSpotlightUserRepository extends RealmRepository implements SpotlightUserRepository {
private final String hostname;
......@@ -26,8 +25,7 @@ public class RealmSpotlightUserRepository extends RealmRepository
}
@Override
public Flowable<List<SpotlightUser>> getSuggestionsFor(String name, SortDirection direction,
int limit) {
public Flowable<List<SpotlightUser>> getSuggestionsFor(String name, SortDirection direction, int limit) {
return Flowable.defer(() -> Flowable.using(
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(
......
package chat.rocket.persistence.realm.models.ddp
import org.json.JSONArray
import org.junit.Test
import org.skyscreamer.jsonassert.JSONAssert
class RealmSpotlightTest {
@Test
fun customizeUserJsonObjectTest() {
// This is a JSONArray that contains a single simulated user data returned from the R.C server.
val userJSONArray = JSONArray("[{\"_id\":\"1234567890\",\"status\":\"offline\",\"name\":\"John Doe\",\"username\":\"John.doe\"}]")
// We have only one JSONObject, so let's customize it.
RealmSpotlight.customizeUserJSONObject(userJSONArray.getJSONObject(0))
// The desired JSON array we want.
val expectedUserJSONArray = JSONArray("[{\"_id\":\"1234567890\",\"name\":\"John.doe\",\"t\":\"d\"}]")
JSONAssert.assertEquals(expectedUserJSONArray, userJSONArray, false)
}
}
\ No newline at end of file
package chat.rocket.core.models;
import com.google.auto.value.AutoValue;
@AutoValue
public abstract class Spotlight {
public abstract String getId();
public abstract String getName();
public abstract String getType();
public static Spotlight.Builder builder() {
return new AutoValue_Spotlight.Builder();
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setId(String id);
public abstract Builder setName(String name);
public abstract Builder setType(String type);
public abstract Spotlight build();
}
}
\ No newline at end of file
package chat.rocket.core.repositories
import chat.rocket.core.models.Spotlight
import io.reactivex.Flowable
interface SpotlightRepository {
fun getSuggestionsFor(term: String, limit: Int): Flowable<List<Spotlight>>
}
\ No newline at end of file
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