Commit b7a175d8 authored by Leonardo Aramaki's avatar Leonardo Aramaki

Merge branch 'develop' into feature/multi-server

parents 3dfd5163 0103fdb6
# Rocket.Chat Android native application
[![CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat.Android/tree/develop.svg?style=shield)](https://circleci.com/gh/RocketChat/Rocket.Chat.Android/tree/develop) [![Build Status](https://travis-ci.org/RocketChat/Rocket.Chat.Android.svg?branch=develop)](https://travis-ci.org/RocketChat/Rocket.Chat.Android) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/a81156a8682e4649994270d3670c3c83)](https://www.codacy.com/app/matheusjardimb/Rocket.Chat.Android) [![CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat.Android/tree/develop.svg?style=shield)](https://circleci.com/gh/RocketChat/Rocket.Chat.Android/tree/develop) [![Build Status](https://travis-ci.org/RocketChat/Rocket.Chat.Android.svg?branch=develop)](https://travis-ci.org/RocketChat/Rocket.Chat.Android) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/a81156a8682e4649994270d3670c3c83)](https://www.codacy.com/app/matheusjardimb/Rocket.Chat.Android)
# Rocket.Chat.Android # Get it from Google Play
Rocket.Chat Native Android Application.
[![Rocket.Chat on Google Play](https://user-images.githubusercontent.com/551004/29770692-a20975c6-8bc6-11e7-8ab0-1cde275496e0.png)](https://play.google.com/store/apps/details?id=chat.rocket.android)
## How to build ## How to build
......
...@@ -45,8 +45,8 @@ android { ...@@ -45,8 +45,8 @@ android {
applicationId "chat.rocket.android" applicationId "chat.rocket.android"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 31 versionCode 34
versionName "1.0.17" versionName "1.0.18"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
multiDexEnabled true multiDexEnabled true
......
...@@ -483,7 +483,11 @@ public class MethodCallHelper { ...@@ -483,7 +483,11 @@ public class MethodCallHelper {
final JSONObject result = task.getResult(); final JSONObject result = task.getResult();
JSONArray roomJsonArray = (JSONArray) result.get("rooms"); JSONArray roomJsonArray = (JSONArray) result.get("rooms");
if (roomJsonArray.length() > 0) { int roomTotal = roomJsonArray.length();
if (roomTotal > 0) {
for (int i = 0; i < roomTotal; ++i) {
RealmSpotlight.Companion.customizeRoomJSONObject(roomJsonArray.getJSONObject(i));
}
jsonString = roomJsonArray.toString(); jsonString = roomJsonArray.toString();
} }
......
...@@ -47,9 +47,6 @@ abstract class AbstractChatRoomFragment extends AbstractFragment { ...@@ -47,9 +47,6 @@ abstract class AbstractChatRoomFragment extends AbstractFragment {
case User.STATUS_AWAY: case User.STATUS_AWAY:
roomToolbar.showUserStatusIcon(RoomToolbar.STATUS_AWAY); roomToolbar.showUserStatusIcon(RoomToolbar.STATUS_AWAY);
break; break;
case User.STATUS_OFFLINE:
roomToolbar.showUserStatusIcon(RoomToolbar.STATUS_OFFLINE);
break;
default: default:
roomToolbar.showUserStatusIcon(RoomToolbar.STATUS_OFFLINE); roomToolbar.showUserStatusIcon(RoomToolbar.STATUS_OFFLINE);
break; break;
......
...@@ -2,10 +2,10 @@ package chat.rocket.android.fragment.sidebar; ...@@ -2,10 +2,10 @@ package chat.rocket.android.fragment.sidebar;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import chat.rocket.core.models.RoomSidebar;
import io.reactivex.Flowable; import io.reactivex.Flowable;
import java.util.List; import java.util.List;
import chat.rocket.android.shared.BaseContract; import chat.rocket.android.shared.BaseContract;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.Spotlight; import chat.rocket.core.models.Spotlight;
import chat.rocket.core.models.User; import chat.rocket.core.models.User;
...@@ -17,14 +17,14 @@ public interface SidebarMainContract { ...@@ -17,14 +17,14 @@ public interface SidebarMainContract {
void showEmptyScreen(); void showEmptyScreen();
void showRoomList(@NonNull List<Room> roomList); void showRoomSidebarList(@NonNull List<RoomSidebar> roomSidebarList);
void show(User user); void show(User user);
} }
interface Presenter extends BaseContract.Presenter<View> { interface Presenter extends BaseContract.Presenter<View> {
void onRoomSelected(Room room); void onRoomSelected(RoomSidebar roomSidebar);
void onSpotlightSelected(Spotlight spotlight); void onSpotlightSelected(Spotlight spotlight);
......
...@@ -11,6 +11,7 @@ import android.support.v7.widget.SearchView; ...@@ -11,6 +11,7 @@ import android.support.v7.widget.SearchView;
import android.view.View; import android.view.View;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.TextView; import android.widget.TextView;
import chat.rocket.android.BuildConfig; import chat.rocket.android.BuildConfig;
import chat.rocket.android.R; import chat.rocket.android.R;
import chat.rocket.android.RocketChatCache; import chat.rocket.android.RocketChatCache;
...@@ -29,7 +30,7 @@ import chat.rocket.android.layouthelper.chatroom.roomlist.UnreadRoomListHeader; ...@@ -29,7 +30,7 @@ import chat.rocket.android.layouthelper.chatroom.roomlist.UnreadRoomListHeader;
import chat.rocket.android.renderer.UserRenderer; import chat.rocket.android.renderer.UserRenderer;
import chat.rocket.core.interactors.RoomInteractor; import chat.rocket.core.interactors.RoomInteractor;
import chat.rocket.core.interactors.SessionInteractor; import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.core.models.Room; import chat.rocket.core.models.RoomSidebar;
import chat.rocket.core.models.Spotlight; import chat.rocket.core.models.Spotlight;
import chat.rocket.core.models.User; import chat.rocket.core.models.User;
import chat.rocket.persistence.realm.repositories.RealmRoomRepository; import chat.rocket.persistence.realm.repositories.RealmRoomRepository;
...@@ -123,9 +124,9 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain ...@@ -123,9 +124,9 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
adapter = new RoomListAdapter(); adapter = new RoomListAdapter();
adapter.setOnItemClickListener(new RoomListAdapter.OnItemClickListener() { adapter.setOnItemClickListener(new RoomListAdapter.OnItemClickListener() {
@Override @Override
public void onItemClick(Room room) { public void onItemClick(RoomSidebar roomSidebar) {
searchView.clearFocus(); searchView.clearFocus();
presenter.onRoomSelected(room); presenter.onRoomSelected(roomSidebar);
} }
@Override @Override
...@@ -142,7 +143,7 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain ...@@ -142,7 +143,7 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
RxSearchView.queryTextChanges(searchView) RxSearchView.queryTextChanges(searchView)
.compose(bindToLifecycle()) .compose(bindToLifecycle())
.debounce(300, TimeUnit.MILLISECONDS) .debounce(100, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.switchMap(charSequence -> { .switchMap(charSequence -> {
if (charSequence.length() == 0) { if (charSequence.length() == 0) {
...@@ -187,8 +188,8 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain ...@@ -187,8 +188,8 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
} }
@Override @Override
public void showRoomList(@NonNull List<Room> roomList) { public void showRoomSidebarList(@NonNull List<RoomSidebar> roomSidebarList) {
adapter.setRooms(roomList); adapter.setRoomSidebarList(roomSidebarList);
} }
@Override @Override
...@@ -228,12 +229,9 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain ...@@ -228,12 +229,9 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
private void updateRoomListMode(User user) { private void updateRoomListMode(User user) {
final List<RoomListHeader> roomListHeaders = new ArrayList<>(); final List<RoomListHeader> roomListHeaders = new ArrayList<>();
if (user != null && user.getSettings() != null && user.getSettings().getPreferences() != null
&& user.getSettings().getPreferences().isUnreadRoomsMode()) {
roomListHeaders.add(new UnreadRoomListHeader( roomListHeaders.add(new UnreadRoomListHeader(
getString(R.string.fragment_sidebar_main_unread_rooms_title) getString(R.string.fragment_sidebar_main_unread_rooms_title)
)); ));
}
roomListHeaders.add(new FavoriteRoomListHeader( roomListHeaders.add(new FavoriteRoomListHeader(
getString(R.string.fragment_sidebar_main_favorite_title) getString(R.string.fragment_sidebar_main_favorite_title)
......
...@@ -3,11 +3,8 @@ package chat.rocket.android.fragment.sidebar; ...@@ -3,11 +3,8 @@ package chat.rocket.android.fragment.sidebar;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.util.Pair; import android.support.v4.util.Pair;
import chat.rocket.core.models.Spotlight; import java.util.ArrayList;
import chat.rocket.persistence.realm.repositories.RealmSpotlightRepository; import java.util.List;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import chat.rocket.android.BackgroundLooper; import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.RocketChatCache; import chat.rocket.android.RocketChatCache;
...@@ -19,19 +16,25 @@ import chat.rocket.android.helper.TextUtils; ...@@ -19,19 +16,25 @@ import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.shared.BasePresenter; import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.interactors.RoomInteractor; import chat.rocket.core.interactors.RoomInteractor;
import chat.rocket.core.models.Room; import chat.rocket.core.models.Room;
import chat.rocket.core.models.RoomSidebar;
import chat.rocket.core.models.Spotlight;
import chat.rocket.core.models.User; import chat.rocket.core.models.User;
import chat.rocket.core.repositories.SpotlightRepository;
import chat.rocket.core.repositories.UserRepository; import chat.rocket.core.repositories.UserRepository;
import java.util.List; import chat.rocket.persistence.realm.repositories.RealmSpotlightRepository;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
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 final String hostname;
private String userId;
private final RoomInteractor roomInteractor; private final RoomInteractor roomInteractor;
private final UserRepository userRepository; private final UserRepository userRepository;
private final RocketChatCache rocketChatCache; private final RocketChatCache rocketChatCache;
private final AbsoluteUrlHelper absoluteUrlHelper; private final AbsoluteUrlHelper absoluteUrlHelper;
private final MethodCallHelper methodCallHelper; private final MethodCallHelper methodCallHelper;
private RealmSpotlightRepository realmSpotlightRepository; private SpotlightRepository realmSpotlightRepository;
private List<RoomSidebar> roomSidebarList;
public SidebarMainPresenter(String hostname, public SidebarMainPresenter(String hostname,
RoomInteractor roomInteractor, RoomInteractor roomInteractor,
...@@ -69,20 +72,14 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View ...@@ -69,20 +72,14 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View
) )
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get())) .subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe( .subscribe(pair -> view.show(pair.first.orNull()), Logger::report);
pair -> {
userId = pair.first.orNull().getId();
view.show(pair.first.orNull());
},
Logger::report
);
addSubscription(subscription); addSubscription(subscription);
} }
@Override @Override
public void onRoomSelected(Room room) { public void onRoomSelected(RoomSidebar roomSidebar) {
rocketChatCache.setSelectedRoomId(room.getRoomId()); rocketChatCache.setSelectedRoomId(roomSidebar.getRoomId());
} }
@Override @Override
...@@ -143,14 +140,65 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View ...@@ -143,14 +140,65 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View
.distinctUntilChanged() .distinctUntilChanged()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get())) .subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe( .subscribe(this::processRooms, Logger::report);
rooms -> view.showRoomList(rooms), addSubscription(subscription);
Logger::report }
);
private void processRooms(List<Room> roomList) {
roomSidebarList = new ArrayList<>();
List<String> userToObserverList = new ArrayList<>();
for (Room room : roomList) {
String roomName = room.getName();
String roomType = room.getType();
RoomSidebar roomSidebar = new RoomSidebar();
roomSidebar.setId(room.getId());
roomSidebar.setRoomId(room.getRoomId());
roomSidebar.setRoomName(roomName);
roomSidebar.setType(roomType);
roomSidebar.setAlert(room.isAlert());
roomSidebar.setFavorite(room.isFavorite());
roomSidebar.setUnread(room.getUnread());
roomSidebar.setUpdateAt(room.getUpdatedAt());
roomSidebar.setLastSeen(room.getLastSeen());
if (roomType.equals(Room.TYPE_DIRECT_MESSAGE)) {
userToObserverList.add(roomName);
}
roomSidebarList.add(roomSidebar);
}
if (userToObserverList.isEmpty()) {
view.showRoomSidebarList(roomSidebarList);
} else {
getUsersStatus();
}
}
private void getUsersStatus() {
// TODO Filter when Android Studion uses the java8 features (removeIf).
// .filter(userList -> userList.removeIf(user -> !userToObserverList.contains(user.getUsername())))
final Disposable subscription = userRepository.getAll()
.distinctUntilChanged()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::processUsers, Logger::report);
addSubscription(subscription); addSubscription(subscription);
} }
private void processUsers(List<User> userList) {
for (User user: userList) {
for(RoomSidebar roomSidebar: roomSidebarList) {
if (roomSidebar.getRoomName().equals(user.getUsername())) {
roomSidebar.setUserStatus(user.getStatus());
}
}
}
view.showRoomSidebarList(roomSidebarList);
}
private void updateCurrentUserStatus(String status) { private void updateCurrentUserStatus(String status) {
methodCallHelper.setUserStatus(status).continueWith(new LogIfError()); methodCallHelper.setUserStatus(status).continueWith(new LogIfError());
} }
......
...@@ -2,6 +2,7 @@ package chat.rocket.android.layouthelper.chatroom.roomlist; ...@@ -2,6 +2,7 @@ package chat.rocket.android.layouthelper.chatroom.roomlist;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import chat.rocket.core.models.RoomSidebar;
import java.util.List; import java.util.List;
import chat.rocket.core.models.Room; import chat.rocket.core.models.Room;
...@@ -21,12 +22,12 @@ public class ChannelRoomListHeader implements RoomListHeader { ...@@ -21,12 +22,12 @@ public class ChannelRoomListHeader implements RoomListHeader {
} }
@Override @Override
public boolean owns(Room room) { public boolean owns(RoomSidebar roomSidebar) {
return room.isChannel() || room.isPrivate(); return roomSidebar.getType().equals(Room.TYPE_CHANNEL) || roomSidebar.getType().equals(Room.TYPE_PRIVATE);
} }
@Override @Override
public boolean shouldShow(@NonNull List<Room> roomList) { public boolean shouldShow(@NonNull List<RoomSidebar> roomSidebarList) {
return true; return true;
} }
......
...@@ -2,6 +2,7 @@ package chat.rocket.android.layouthelper.chatroom.roomlist; ...@@ -2,6 +2,7 @@ package chat.rocket.android.layouthelper.chatroom.roomlist;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import chat.rocket.core.models.RoomSidebar;
import java.util.List; import java.util.List;
import chat.rocket.core.models.Room; import chat.rocket.core.models.Room;
...@@ -21,12 +22,12 @@ public class DirectMessageRoomListHeader implements RoomListHeader { ...@@ -21,12 +22,12 @@ public class DirectMessageRoomListHeader implements RoomListHeader {
} }
@Override @Override
public boolean owns(Room room) { public boolean owns(RoomSidebar roomSidebar) {
return room.isDirectMessage(); return roomSidebar.getType().equals(Room.TYPE_DIRECT_MESSAGE);
} }
@Override @Override
public boolean shouldShow(@NonNull List<Room> roomList) { public boolean shouldShow(@NonNull List<RoomSidebar> roomSidebarList) {
return true; return true;
} }
......
...@@ -2,8 +2,8 @@ package chat.rocket.android.layouthelper.chatroom.roomlist; ...@@ -2,8 +2,8 @@ package chat.rocket.android.layouthelper.chatroom.roomlist;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import chat.rocket.core.models.RoomSidebar;
import java.util.List; import java.util.List;
import chat.rocket.core.models.Room;
public class FavoriteRoomListHeader implements RoomListHeader { public class FavoriteRoomListHeader implements RoomListHeader {
...@@ -19,18 +19,17 @@ public class FavoriteRoomListHeader implements RoomListHeader { ...@@ -19,18 +19,17 @@ public class FavoriteRoomListHeader implements RoomListHeader {
} }
@Override @Override
public boolean owns(Room room) { public boolean owns(RoomSidebar roomSidebar) {
return room.isFavorite(); return roomSidebar.isFavorite();
} }
@Override @Override
public boolean shouldShow(@NonNull List<Room> roomList) { public boolean shouldShow(@NonNull List<RoomSidebar> roomSidebarList) {
for (int i = 0, size = roomList.size(); i < size; i++) { for (RoomSidebar roomSidebar: roomSidebarList) {
if (roomList.get(i).isFavorite()) { if (roomSidebar.isFavorite()) {
return true; return true;
} }
} }
return false; return false;
} }
......
...@@ -5,6 +5,7 @@ import android.support.v7.widget.RecyclerView; ...@@ -5,6 +5,7 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.ViewGroup; import android.view.ViewGroup;
import chat.rocket.core.models.RoomSidebar;
import chat.rocket.core.models.Spotlight; import chat.rocket.core.models.Spotlight;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
...@@ -12,7 +13,6 @@ import java.util.List; ...@@ -12,7 +13,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import chat.rocket.android.R; import chat.rocket.android.R;
import chat.rocket.android.widget.internal.RoomListItemView; import chat.rocket.android.widget.internal.RoomListItemView;
import chat.rocket.core.models.Room;
public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
...@@ -22,7 +22,7 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde ...@@ -22,7 +22,7 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
private static final int VIEW_TYPE_HEADER = 0; private static final int VIEW_TYPE_HEADER = 0;
private static final int VIEW_TYPE_ROOM = 1; private static final int VIEW_TYPE_ROOM = 1;
private List<Room> roomList = Collections.emptyList(); private List<RoomSidebar> roomSidebarList = Collections.emptyList();
private List<Spotlight> spotlightList = Collections.emptyList(); private List<Spotlight> spotlightList = Collections.emptyList();
private List<RoomListHeader> roomListHeaders = Collections.emptyList(); private List<RoomListHeader> roomListHeaders = Collections.emptyList();
private Map<Integer, RoomListHeader> headersPosition = new HashMap<>(); private Map<Integer, RoomListHeader> headersPosition = new HashMap<>();
...@@ -32,9 +32,9 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde ...@@ -32,9 +32,9 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
private OnItemClickListener externalListener; private OnItemClickListener externalListener;
private OnItemClickListener listener = new OnItemClickListener() { private OnItemClickListener listener = new OnItemClickListener() {
@Override @Override
public void onItemClick(Room room) { public void onItemClick(RoomSidebar roomSidebar) {
if (externalListener != null) { if (externalListener != null) {
externalListener.onItemClick(room); externalListener.onItemClick(roomSidebar);
} }
} }
...@@ -48,17 +48,17 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde ...@@ -48,17 +48,17 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
public void setRoomListHeaders(@NonNull List<RoomListHeader> roomListHeaders) { public void setRoomListHeaders(@NonNull List<RoomListHeader> roomListHeaders) {
this.roomListHeaders = roomListHeaders; this.roomListHeaders = roomListHeaders;
updateRoomList(); updateRoomSidebarList();
} }
public void setRooms(@NonNull List<Room> roomList) { public void setRoomSidebarList(@NonNull List<RoomSidebar> roomSidebarList) {
this.roomList = roomList; this.roomSidebarList = roomSidebarList;
updateRoomList(); updateRoomSidebarList();
} }
public void setSpotlightList(@NonNull List<Spotlight> spotlightList) { public void setSpotlightList(@NonNull List<Spotlight> spotlightList) {
this.spotlightList = spotlightList; this.spotlightList = spotlightList;
updateRoomList(); updateRoomSidebarList();
} }
public void setMode(int mode) { public void setMode(int mode) {
...@@ -77,8 +77,8 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde ...@@ -77,8 +77,8 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_HEADER) { if (viewType == VIEW_TYPE_HEADER) {
return new RoomListHeaderViewHolder( return new RoomListHeaderViewHolder(LayoutInflater
LayoutInflater.from(parent.getContext()) .from(parent.getContext())
.inflate(R.layout.room_list_header, parent, false) .inflate(R.layout.room_list_header, parent, false)
); );
} }
...@@ -89,13 +89,12 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde ...@@ -89,13 +89,12 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (mode == MODE_ROOM) { if (mode == MODE_ROOM) {
if (getItemViewType(position) == VIEW_TYPE_HEADER) { if (getItemViewType(position) == VIEW_TYPE_HEADER) {
((RoomListHeaderViewHolder) holder) ((RoomListHeaderViewHolder) holder).bind(headersPosition.get(position));
.bind(headersPosition.get(position));
return; return;
} }
((RoomListItemViewHolder) holder) RoomSidebar roomSidebar = roomSidebarList.get(position - getTotalHeadersBeforePosition(position));
.bind(roomList.get(position - getTotalHeadersBeforePosition(position))); ((RoomListItemViewHolder) holder).bind(roomSidebar);
} else if (mode == MODE_SPOTLIGHT) { } else if (mode == MODE_SPOTLIGHT) {
((RoomListItemViewHolder) holder).bind(spotlightList.get(position)); ((RoomListItemViewHolder) holder).bind(spotlightList.get(position));
} }
...@@ -106,7 +105,7 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde ...@@ -106,7 +105,7 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
if (mode == MODE_SPOTLIGHT) { if (mode == MODE_SPOTLIGHT) {
return spotlightList.size(); return spotlightList.size();
} }
return roomList.size() + headersPosition.size(); return roomSidebarList.size() + headersPosition.size();
} }
@Override @Override
...@@ -121,7 +120,7 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde ...@@ -121,7 +120,7 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
return VIEW_TYPE_ROOM; return VIEW_TYPE_ROOM;
} }
private void updateRoomList() { private void updateRoomSidebarList() {
if (mode == MODE_ROOM) { if (mode == MODE_ROOM) {
sortRoomList(); sortRoomList();
calculateHeadersPosition(); calculateHeadersPosition();
...@@ -132,18 +131,18 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde ...@@ -132,18 +131,18 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
private void sortRoomList() { private void sortRoomList() {
int totalHeaders = roomListHeaders.size(); int totalHeaders = roomListHeaders.size();
Collections.sort(roomList, (room, anotherRoom) -> { Collections.sort(roomSidebarList, (roomSidebar, anotherRoom) -> {
for (int i = 0; i < totalHeaders; i++) { for (int i = 0; i < totalHeaders; i++) {
final RoomListHeader header = roomListHeaders.get(i); final RoomListHeader header = roomListHeaders.get(i);
if (header.owns(room) && !header.owns(anotherRoom)) { if (header.owns(roomSidebar) && !header.owns(anotherRoom)) {
return -1; return -1;
} else if (!header.owns(room) && header.owns(anotherRoom)) { } else if (!header.owns(roomSidebar) && header.owns(anotherRoom)) {
return 1; return 1;
} }
} }
return room.getName().compareTo(anotherRoom.getName()); return roomSidebar.getRoomName().compareTo(anotherRoom.getRoomName());
}); });
} }
...@@ -151,19 +150,19 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde ...@@ -151,19 +150,19 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
headersPosition.clear(); headersPosition.clear();
int roomIdx = 0; int roomIdx = 0;
int totalRooms = roomList.size(); int totalRooms = roomSidebarList.size();
int totalHeaders = roomListHeaders.size(); int totalHeaders = roomListHeaders.size();
for (int i = 0; i < totalHeaders; i++) { for (int i = 0; i < totalHeaders; i++) {
final RoomListHeader header = roomListHeaders.get(i); final RoomListHeader header = roomListHeaders.get(i);
if (!header.shouldShow(roomList)) { if (!header.shouldShow(roomSidebarList)) {
continue; continue;
} }
headersPosition.put(roomIdx + headersPosition.size(), header); headersPosition.put(roomIdx + headersPosition.size(), header);
for (; roomIdx < totalRooms; roomIdx++) { for (; roomIdx < totalRooms; roomIdx++) {
final Room room = roomList.get(roomIdx); final RoomSidebar roomSidebar = roomSidebarList.get(roomIdx);
if (!header.owns(room)) { if (!header.owns(roomSidebar)) {
break; break;
} }
} }
...@@ -185,7 +184,7 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde ...@@ -185,7 +184,7 @@ public class RoomListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
} }
public interface OnItemClickListener { public interface OnItemClickListener {
void onItemClick(Room room); void onItemClick(RoomSidebar roomSidebar);
void onItemClick(Spotlight spotlight); void onItemClick(Spotlight spotlight);
} }
......
...@@ -2,16 +2,16 @@ package chat.rocket.android.layouthelper.chatroom.roomlist; ...@@ -2,16 +2,16 @@ package chat.rocket.android.layouthelper.chatroom.roomlist;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import chat.rocket.core.models.RoomSidebar;
import java.util.List; import java.util.List;
import chat.rocket.core.models.Room;
public interface RoomListHeader { public interface RoomListHeader {
String getTitle(); String getTitle();
boolean owns(Room room); boolean owns(RoomSidebar roomSidebar);
boolean shouldShow(@NonNull List<Room> roomList); boolean shouldShow(@NonNull List<RoomSidebar> roomSidebarList);
ClickListener getClickListener(); ClickListener getClickListener();
......
...@@ -14,8 +14,8 @@ public class RoomListHeaderViewHolder extends RecyclerView.ViewHolder { ...@@ -14,8 +14,8 @@ public class RoomListHeaderViewHolder extends RecyclerView.ViewHolder {
public RoomListHeaderViewHolder(View itemView) { public RoomListHeaderViewHolder(View itemView) {
super(itemView); super(itemView);
title = (TextView) itemView.findViewById(R.id.title); title = itemView.findViewById(R.id.title);
button = (Button) itemView.findViewById(R.id.btn_add); button = itemView.findViewById(R.id.btn_add);
} }
public void bind(RoomListHeader roomListHeader) { public void bind(RoomListHeader roomListHeader) {
......
...@@ -4,43 +4,99 @@ import android.support.v7.widget.RecyclerView; ...@@ -4,43 +4,99 @@ import android.support.v7.widget.RecyclerView;
import chat.rocket.android.widget.internal.RoomListItemView; import chat.rocket.android.widget.internal.RoomListItemView;
import chat.rocket.core.models.Room; import chat.rocket.core.models.Room;
import chat.rocket.core.models.RoomSidebar;
import chat.rocket.core.models.Spotlight; import chat.rocket.core.models.Spotlight;
import chat.rocket.core.models.User;
public class RoomListItemViewHolder extends RecyclerView.ViewHolder { public class RoomListItemViewHolder extends RecyclerView.ViewHolder {
public RoomListItemViewHolder(RoomListItemView itemView, private RoomListItemView itemView;
RoomListAdapter.OnItemClickListener listener) {
public RoomListItemViewHolder(RoomListItemView itemView, RoomListAdapter.OnItemClickListener listener) {
super(itemView); super(itemView);
itemView.setOnClickListener(view -> { this.itemView = itemView;
if (listener != null) {
Object tag = view.getTag();
if (tag instanceof Room) { itemView.setOnClickListener(view -> {
listener.onItemClick((Room) view.getTag()); Object object = view.getTag();
} else if (tag instanceof Spotlight) { if (object instanceof RoomSidebar) {
listener.onItemClick((Spotlight) view.getTag()); listener.onItemClick((RoomSidebar)object);
} } else if (object instanceof Spotlight) {
listener.onItemClick((Spotlight)object);
} }
}); });
} }
public void bind(Room room) { public void bind(RoomSidebar roomSidebar) {
((RoomListItemView) itemView) itemView.setRoomId(roomSidebar.getRoomId());
.setRoomId(room.getRoomId()) itemView.setRoomName(roomSidebar.getRoomName());
.setRoomName(room.getName()) itemView.setAlert(roomSidebar.isAlert());
.setRoomType(room.getType()) itemView.setUnreadCount(roomSidebar.getUnread());
.setAlert(room.isAlert()) itemView.setTag(roomSidebar);
.setUnreadCount(room.getUnread())
.setTag(room); String roomType = roomSidebar.getType();
if (roomType.equals(Room.TYPE_DIRECT_MESSAGE)) {
showUserStatusIcon(roomSidebar.getUserStatus());
} else {
showRoomIcon(roomType);
}
} }
public void bind(Spotlight spotlight) { public void bind(Spotlight spotlight) {
((RoomListItemView) itemView) itemView.setRoomId(spotlight.getId());
.setRoomId(spotlight.getId()) itemView.setRoomName(spotlight.getName());
.setRoomName(spotlight.getName()) itemView.setAlert(false);
.setRoomType(spotlight.getType()) itemView.setUnreadCount(0);
.setAlert(false) itemView.setTag(spotlight);
.setUnreadCount(0)
.setTag(spotlight); String roomType = spotlight.getType();
if (roomType.equals(Room.TYPE_DIRECT_MESSAGE)) {
showUserStatusIcon(spotlight.getStatus());
} else {
showRoomIcon(roomType);
}
}
/**
* Shows the user status icon.
* @param userStatus The user status to show the correspondent icon.
* @see User
*/
private void showUserStatusIcon(String userStatus) {
if (userStatus == null) {
itemView.showOfflineUserStatusIcon();
} else {
switch (userStatus) {
case User.STATUS_ONLINE:
itemView.showOnlineUserStatusIcon();
break;
case User.STATUS_BUSY:
itemView.showBusyUserStatusIcon();
break;
case User.STATUS_AWAY:
itemView.showAwayUserStatusIcon();
break;
default:
itemView.showOfflineUserStatusIcon();
break;
}
}
}
/**
* Only shows the room icon if it is a PRIVATE CHANNEL or PUBLIC CHANNEL, otherwise you should use {@link #showUserStatusIcon(String)} to show the icon.
* @param roomType The type of Room.
* @see Room
*/
private void showRoomIcon(String roomType) {
switch (roomType) {
case Room.TYPE_CHANNEL:
itemView.showPublicChannelIcon();
break;
case Room.TYPE_PRIVATE:
itemView.showPrivateChannelIcon();
break;
default:
throw new AssertionError("Room type doesn't satisfies the method documentation. Room type is:" + roomType);
}
} }
} }
\ No newline at end of file
...@@ -2,8 +2,8 @@ package chat.rocket.android.layouthelper.chatroom.roomlist; ...@@ -2,8 +2,8 @@ package chat.rocket.android.layouthelper.chatroom.roomlist;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import chat.rocket.core.models.RoomSidebar;
import java.util.List; import java.util.List;
import chat.rocket.core.models.Room;
public class UnreadRoomListHeader implements RoomListHeader { public class UnreadRoomListHeader implements RoomListHeader {
...@@ -19,18 +19,17 @@ public class UnreadRoomListHeader implements RoomListHeader { ...@@ -19,18 +19,17 @@ public class UnreadRoomListHeader implements RoomListHeader {
} }
@Override @Override
public boolean owns(Room room) { public boolean owns(RoomSidebar roomSidebar) {
return room.isAlert(); return roomSidebar.isAlert();
} }
@Override @Override
public boolean shouldShow(@NonNull List<Room> roomList) { public boolean shouldShow(@NonNull List<RoomSidebar> roomSidebarList) {
for (int i = 0, size = roomList.size(); i < size; i++) { for (RoomSidebar roomSidebar: roomSidebarList) {
if (roomList.get(i).isAlert()) { if (roomSidebar.isAlert()) {
return true; return true;
} }
} }
return false; return false;
} }
......
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M16.5,6v11.5c0,2.21 -1.79,4 -4,4s-4,-1.79 -4,-4V5c0,-1.38 1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5v10.5c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1V6H10v9.5c0,1.38 1.12,2.5 2.5,2.5s2.5,-1.12 2.5,-2.5V5c0,-2.21 -1.79,-4 -4,-4S7,2.79 7,5v12.5c0,3.04 2.46,5.5 5.5,5.5s5.5,-2.46 5.5,-5.5V6h-1.5z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:alpha="0.78"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0"
android:width="24dp">
<path
android:fillColor="#FF000000"
android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
</vector>
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center" android:gravity="center"
android:orientation="vertical" android:orientation="vertical"
android:theme="@style/Theme.AppCompat.Light"> android:background="@android:color/white">
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
......
...@@ -10,21 +10,26 @@ open class RealmSpotlight : RealmObject() { ...@@ -10,21 +10,26 @@ open class RealmSpotlight : RealmObject() {
@PrimaryKey var _id: String? = null @PrimaryKey var _id: String? = null
var name: String? = null var name: String? = null
var t: String? = null var t: String? = null
var status: String? = null
fun asSpotlight(): Spotlight { fun asSpotlight(): Spotlight {
return Spotlight.builder() return Spotlight.builder()
.setId(_id) .setId(_id)
.setName(name) .setName(name)
.setType(t) .setType(t)
.setStatus(status)
.build() .build()
} }
companion object { companion object {
fun customizeRoomJSONObject(roomJsonObject: JSONObject) {
roomJsonObject.put(Columns.STATUS, "")
}
fun customizeUserJSONObject(userJsonObject: JSONObject) { fun customizeUserJSONObject(userJsonObject: JSONObject) {
userJsonObject.put(Columns.NAME, userJsonObject.get("username")) userJsonObject.put(Columns.NAME, userJsonObject.get("username"))
userJsonObject.put(Columns.TYPE, "d") userJsonObject.put(Columns.TYPE, "d")
userJsonObject.remove("username") userJsonObject.remove("username")
userJsonObject.remove("status")
} }
} }
...@@ -33,6 +38,7 @@ open class RealmSpotlight : RealmObject() { ...@@ -33,6 +38,7 @@ open class RealmSpotlight : RealmObject() {
const val ID = "_id" const val ID = "_id"
const val NAME = "name" const val NAME = "name"
const val TYPE = "t" const val TYPE = "t"
const val STATUS = "status"
} }
} }
} }
\ No newline at end of file
...@@ -107,7 +107,6 @@ public class RealmRoomRepository extends RealmRepository implements RoomReposito ...@@ -107,7 +107,6 @@ public class RealmRoomRepository extends RealmRepository implements RoomReposito
if (optional.isPresent()) { if (optional.isPresent()) {
return Optional.of(optional.get().asRoomHistoryState()); return Optional.of(optional.get().asRoomHistoryState());
} }
return Optional.absent(); return Optional.absent();
})); }));
} }
......
...@@ -27,6 +27,21 @@ public class RealmUserRepository extends RealmRepository implements UserReposito ...@@ -27,6 +27,21 @@ public class RealmUserRepository extends RealmRepository implements UserReposito
this.hostname = hostname; this.hostname = hostname;
} }
@Override
public Flowable<List<User>> getAll() {
return Flowable.defer(() -> Flowable.using(
() -> new Pair<>(RealmStore.getRealm(hostname), Looper.myLooper()),
pair -> RxJavaInterop.toV2Flowable(
pair.first.where(RealmUser.class)
.findAll()
.asObservable()),
pair -> close(pair.first, pair.second))
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()))
.filter(roomSubscriptions -> roomSubscriptions != null && roomSubscriptions.isLoaded()
&& roomSubscriptions.isValid())
.map(this::toList));
}
@Override @Override
public Flowable<Optional<User>> getCurrent() { public Flowable<Optional<User>> getCurrent() {
return Flowable.defer(() -> return Flowable.defer(() ->
......
...@@ -7,7 +7,6 @@ import android.support.annotation.Nullable; ...@@ -7,7 +7,6 @@ import android.support.annotation.Nullable;
import android.support.annotation.StringRes; import android.support.annotation.StringRes;
import android.support.graphics.drawable.VectorDrawableCompat; import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.graphics.drawable.DrawerArrowDrawable; import android.support.v7.graphics.drawable.DrawerArrowDrawable;
import android.support.v7.widget.AppCompatImageView; import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
...@@ -17,6 +16,7 @@ import android.view.View; ...@@ -17,6 +16,7 @@ import android.view.View;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import chat.rocket.android.widget.helper.DrawableHelper;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
...@@ -103,23 +103,24 @@ public class RoomToolbar extends Toolbar { ...@@ -103,23 +103,24 @@ public class RoomToolbar extends Toolbar {
} }
public void showUserStatusIcon(int status) { public void showUserStatusIcon(int status) {
wrapDrawable(userStatusDrawable); DrawableHelper.INSTANCE.wrapDrawable(userStatusDrawable);
Context context = getContext();
switch (status) { switch (status) {
case STATUS_ONLINE: case STATUS_ONLINE:
tintDrawable(userStatusDrawable, R.color.color_user_status_online); DrawableHelper.INSTANCE.tintDrawable(userStatusDrawable, context, R.color.color_user_status_online);
break; break;
case STATUS_BUSY: case STATUS_BUSY:
tintDrawable(userStatusDrawable, R.color.color_user_status_busy); DrawableHelper.INSTANCE.tintDrawable(userStatusDrawable, context, R.color.color_user_status_busy);
break; break;
case STATUS_AWAY: case STATUS_AWAY:
tintDrawable(userStatusDrawable, R.color.color_user_status_away); DrawableHelper.INSTANCE.tintDrawable(userStatusDrawable, context, R.color.color_user_status_away);
break; break;
case STATUS_OFFLINE: case STATUS_OFFLINE:
tintDrawable(userStatusDrawable, R.color.color_user_status_offline); DrawableHelper.INSTANCE.tintDrawable(userStatusDrawable, context, R.color.color_user_status_offline);
break; break;
default: default:
tintDrawable(userStatusDrawable, R.color.color_user_status_offline); DrawableHelper.INSTANCE.tintDrawable(userStatusDrawable, context, R.color.color_user_status_offline);
break; break;
} }
...@@ -128,25 +129,6 @@ public class RoomToolbar extends Toolbar { ...@@ -128,25 +129,6 @@ public class RoomToolbar extends Toolbar {
userStatusImage.setVisibility(VISIBLE); userStatusImage.setVisibility(VISIBLE);
} }
/**
* Wraps a drawable to be used for example for tinting.
* @param drawable The drawable to wrap.
* @see #tintDrawable(Drawable, int)
*/
private void wrapDrawable(Drawable drawable) {
DrawableCompat.wrap(drawable);
}
/**
* REMARK: You MUST always wrap the drawable before tint it.
* @param drawable The drawable to tint.
* @param color The color to tint the drawable.
* @see #wrapDrawable(Drawable)
*/
private void tintDrawable(Drawable drawable, int color) {
DrawableCompat.setTint(drawable, ContextCompat.getColor(getContext(), color));
}
public void setUnreadBudge(int numUnreadChannels, int numMentionsSum) { public void setUnreadBudge(int numUnreadChannels, int numMentionsSum) {
if (getNavigationIcon() == null) { if (getNavigationIcon() == null) {
return; return;
...@@ -166,7 +148,7 @@ public class RoomToolbar extends Toolbar { ...@@ -166,7 +148,7 @@ public class RoomToolbar extends Toolbar {
badgeImageView.setImageDrawable(getBadgeDrawable(numMentionsSum)); badgeImageView.setImageDrawable(getBadgeDrawable(numMentionsSum));
} else { } else {
badgeImageView.setScaleType(ImageView.ScaleType.CENTER); badgeImageView.setScaleType(ImageView.ScaleType.CENTER);
badgeImageView.setImageResource(R.drawable.badge_without_number); badgeImageView.setImageResource(R.drawable.ic_badge_without_number_red_10dp);
} }
badgeImageView.setVisibility(View.VISIBLE); badgeImageView.setVisibility(View.VISIBLE);
} else { } else {
...@@ -180,7 +162,7 @@ public class RoomToolbar extends Toolbar { ...@@ -180,7 +162,7 @@ public class RoomToolbar extends Toolbar {
.beginConfig() .beginConfig()
.useFont(Typeface.SANS_SERIF) .useFont(Typeface.SANS_SERIF)
.endConfig() .endConfig()
.buildRound(icon, ContextCompat.getColor(getContext(), R.color.color_user_status_busy)); .buildRound(icon, ContextCompat.getColor(getContext(), R.color.color_alert));
} }
@Override @Override
......
package chat.rocket.android.widget.helper
import android.content.Context
import android.graphics.drawable.Drawable
import android.support.v4.content.ContextCompat
import android.support.v4.graphics.drawable.DrawableCompat
object DrawableHelper {
/**
* Wraps a drawable to be used for example for tinting.
*
* @param drawable The drawable to wrap.
* @see tintDrawable
*/
fun wrapDrawable(drawable: Drawable) {
DrawableCompat.wrap(drawable)
}
/**
* REMARK: You MUST always wrap the drawable before tint it.
*
* @param drawable The drawable to tint.
* @param context The context.
* @param resId The resource id color to tint the drawable.
* @see wrapDrawable
*/
fun tintDrawable(drawable: Drawable, context: Context, resId: Int) {
DrawableCompat.setTint(drawable, ContextCompat.getColor(context, resId))
}
}
\ No newline at end of file
package chat.rocket.android.widget.internal;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.HashMap;
import chat.rocket.android.widget.R;
/**
* Room list-item view used in sidebar.
*/
public class RoomListItemView extends FrameLayout {
private static HashMap<String, Integer> ICON_TABLE = new HashMap<String, Integer>() {
{
put("c", R.string.fa_hashtag);
put("p", R.string.fa_lock);
put("d", R.string.fa_at);
}
};
private String roomId;
private String roomName;
public RoomListItemView(Context context) {
super(context);
initialize(context);
}
public RoomListItemView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context);
}
public RoomListItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public RoomListItemView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initialize(context);
}
private void initialize(Context context) {
setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
TypedArray array2 = context.getTheme().obtainStyledAttributes(new int[]{
R.attr.selectableItemBackground
});
setBackground(array2.getDrawable(0));
array2.recycle();
View.inflate(context, R.layout.room_list_item, this);
}
public String getRoomId() {
return roomId;
}
public RoomListItemView setRoomId(String roomId) {
this.roomId = roomId;
return this;
}
public RoomListItemView setRoomType(String type) {
if (ICON_TABLE.containsKey(type)) {
TextView icon = (TextView) findViewById(R.id.icon);
icon.setText(ICON_TABLE.get(type));
}
return this;
}
public RoomListItemView setUnreadCount(int count) {
View alertCountContainer = findViewById(R.id.alert_count_container);
TextView alertCount = (TextView) findViewById(R.id.alert_count);
if (count > 0) {
alertCount.setText(Integer.toString(count));
alertCountContainer.setVisibility(View.VISIBLE);
} else {
alertCountContainer.setVisibility(View.GONE);
}
return this;
}
public RoomListItemView setAlert(boolean alert) {
setAlpha(alert ? 1.0f : 0.62f);
return this;
}
public String getRoomName() {
return roomName;
}
public RoomListItemView setRoomName(String roomName) {
this.roomName = roomName;
TextView text = (TextView) findViewById(R.id.text);
text.setText(roomName);
return this;
}
}
package chat.rocket.android.widget.internal
import android.annotation.TargetApi
import android.content.Context
import android.content.res.TypedArray
import android.graphics.drawable.Drawable
import android.os.Build
import android.support.annotation.ColorRes
import android.support.annotation.StringRes
import android.support.graphics.drawable.VectorDrawableCompat
import android.util.AttributeSet
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import chat.rocket.android.widget.R
import chat.rocket.android.widget.helper.DrawableHelper
/**
* Room list-item view used in sidebar.
*/
class RoomListItemView : FrameLayout {
lateinit private var roomId: String
lateinit private var roomTypeImage: ImageView
lateinit private var userStatusImage: ImageView
lateinit private var roomNameText: TextView
lateinit private var alertCountText: TextView
lateinit private var privateChannelDrawable: Drawable
lateinit private var publicChannelDrawable: Drawable
lateinit private var userStatusDrawable: Drawable
constructor(context: Context) : super(context) {
initialize(context)
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
initialize(context)
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
initialize(context)
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
initialize(context)
}
private fun initialize(context: Context) {
layoutParams = LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT)
val array = context
.theme
.obtainStyledAttributes(intArrayOf(R.attr.selectableItemBackground))
background = array.getDrawable(0)
array.recycle()
View.inflate(context, R.layout.room_list_item, this)
roomTypeImage = findViewById(R.id.image_room_type)
userStatusImage = findViewById(R.id.image_user_status)
roomNameText = findViewById(R.id.text_room_name)
alertCountText = findViewById(R.id.text_alert_count)
privateChannelDrawable = VectorDrawableCompat.create(resources, R.drawable.ic_lock_white_24dp, null)!!
publicChannelDrawable = VectorDrawableCompat.create(resources, R.drawable.ic_hashtag_white_24dp, null)!!
userStatusDrawable = VectorDrawableCompat.create(resources, R.drawable.ic_user_status_black_24dp, null)!!
}
fun setRoomId(roomId: String) {
this.roomId = roomId
}
fun setUnreadCount(count: Int) {
if (count > 0) {
alertCountText.text = count.toString()
alertCountText.visibility = View.VISIBLE
} else {
alertCountText.visibility = View.GONE
}
}
fun setAlert(alert: Boolean) {
alpha = if (alert) 1.0f else 0.62f
}
fun setRoomName(roomName: String) {
roomNameText.text = roomName
}
fun showPrivateChannelIcon() {
roomTypeImage.setImageDrawable(privateChannelDrawable)
userStatusImage.visibility = View.GONE
roomTypeImage.visibility = View.VISIBLE
}
fun showPublicChannelIcon() {
roomTypeImage.setImageDrawable(publicChannelDrawable)
userStatusImage.visibility = View.GONE
roomTypeImage.visibility = View.VISIBLE
}
fun showOnlineUserStatusIcon() {
prepareDrawableAndShow(R.color.color_user_status_online)
}
fun showBusyUserStatusIcon() {
prepareDrawableAndShow(R.color.color_user_status_busy)
}
fun showAwayUserStatusIcon() {
prepareDrawableAndShow(R.color.color_user_status_away)
}
fun showOfflineUserStatusIcon() {
prepareDrawableAndShow(R.color.color_user_status_offline)
}
private fun prepareDrawableAndShow(@ColorRes resId: Int) {
DrawableHelper.wrapDrawable(userStatusDrawable)
DrawableHelper.tintDrawable(userStatusDrawable, context, resId)
userStatusImage.setImageDrawable(userStatusDrawable)
roomTypeImage.visibility = View.GONE
userStatusImage.visibility = View.VISIBLE
}
}
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="10dp"
android:height="10dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFF44336"
android:pathData="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" />
</vector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"> android:shape="rectangle">
<solid android:color="@color/badge_color" />
<size android:width="@dimen/badge_size" android:height="@dimen/badge_size"/> <solid
android:color="@color/color_alert" />
<corners
android:radius="4dp" />
</shape> </shape>
\ No newline at end of file
...@@ -2,50 +2,49 @@ ...@@ -2,50 +2,49 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingStart="?attr/listPreferredItemPaddingLeft" android:paddingStart="?attr/listPreferredItemPaddingLeft"
android:paddingEnd="?attr/listPreferredItemPaddingRight"
android:paddingLeft="?attr/listPreferredItemPaddingLeft" android:paddingLeft="?attr/listPreferredItemPaddingLeft"
android:paddingRight="?attr/listPreferredItemPaddingRight" android:paddingRight="?attr/listPreferredItemPaddingRight"
android:paddingEnd="?attr/listPreferredItemPaddingRight"> android:paddingBottom="10dp">
<FrameLayout <ImageView
android:layout_width="32dp" android:id="@+id/image_room_type"
android:layout_height="?attr/listPreferredItemHeightSmall" android:layout_width="20dp"
android:layout_marginEnd="16dp" android:layout_height="wrap_content"
android:layout_marginRight="16dp"> android:visibility="gone" />
<io.github.yusukeiwaki.android.widget.FontAwesomeTextView <ImageView
android:id="@+id/icon" android:id="@+id/image_user_status"
android:layout_width="wrap_content" android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:layout_width="10dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:visibility="gone" />
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
</FrameLayout>
<TextView <TextView
android:id="@+id/text" android:id="@+id/text_room_name"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="?attr/listPreferredItemHeightSmall" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="0.9"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:gravity="center_vertical" android:gravity="center_vertical"
android:textAppearance="@style/TextAppearance.AppCompat.Body2" /> android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
<FrameLayout
android:id="@+id/alert_count_container"
android:layout_width="wrap_content"
android:minWidth="20dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:padding="3dp"
android:layout_gravity="center_vertical"
android:background="@drawable/unread_count_background"
android:layout_marginLeft="8dp">
<TextView <TextView
android:id="@+id/alert_count" android:id="@+id/text_alert_count"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:textSize="14dp" android:layout_weight="0.1"
android:layout_gravity="center" android:gravity="center"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" /> android:textSize="14sp"
</FrameLayout> android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:background="@drawable/style_alert_count"
android:visibility="gone" />
</LinearLayout> </LinearLayout>
\ No newline at end of file
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
android:layout_height="10dp" android:layout_height="10dp"
android:layout_marginRight="10dp" android:layout_marginRight="10dp"
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
android:visibility="gone"/> android:visibility="gone" />
<ImageView <ImageView
android:id="@+id/image_room_type" android:id="@+id/image_room_type"
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
android:layout_height="24dp" android:layout_height="24dp"
android:layout_marginRight="10dp" android:layout_marginRight="10dp"
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
android:visibility="gone"/> android:visibility="gone" />
<TextView <TextView
android:id="@+id/text_toolbar" android:id="@+id/text_toolbar"
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="badge_color">#FFFFFFFF</color>
<dimen name="badge_size">10dp</dimen>
</resources>
\ No newline at end of file
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
<color name="color_timestamp">#FFA8A8A8</color> <color name="color_timestamp">#FFA8A8A8</color>
<color name="color_embed_hostname">@color/color_timestamp</color> <color name="color_embed_hostname">@color/color_timestamp</color>
<color name="color_alert">#FFF44336</color> <!-- Red 500-->
<!-- User status colors--> <!-- User status colors-->
<color name="color_user_status_online">#FF4CAF50</color> <!-- Green 500 --> <color name="color_user_status_online">#FF4CAF50</color> <!-- Green 500 -->
<color name="color_user_status_busy">#FFF44336</color> <!-- Red 500--> <color name="color_user_status_busy">#FFF44336</color> <!-- Red 500-->
......
package chat.rocket.core.models
class RoomSidebar {
lateinit var id: String
lateinit var roomId: String
lateinit var roomName: String
lateinit var type: String
var userStatus: String? = null
var isAlert: Boolean = false
var isFavorite: Boolean = false
var unread: Int = 0
var updateAt: Long = 0
var lastSeen: Long = 0
}
\ No newline at end of file
...@@ -11,6 +11,8 @@ public abstract class Spotlight { ...@@ -11,6 +11,8 @@ public abstract class Spotlight {
public abstract String getType(); public abstract String getType();
public abstract String getStatus();
public static Spotlight.Builder builder() { public static Spotlight.Builder builder() {
return new AutoValue_Spotlight.Builder(); return new AutoValue_Spotlight.Builder();
} }
...@@ -24,6 +26,8 @@ public abstract class Spotlight { ...@@ -24,6 +26,8 @@ public abstract class Spotlight {
public abstract Builder setType(String type); public abstract Builder setType(String type);
public abstract Builder setStatus(String status);
public abstract Spotlight build(); public abstract Spotlight build();
} }
} }
\ No newline at end of file
...@@ -6,6 +6,8 @@ import chat.rocket.core.models.User ...@@ -6,6 +6,8 @@ import chat.rocket.core.models.User
interface UserRepository { interface UserRepository {
fun getAll(): Flowable<List<User>>
fun getCurrent(): Flowable<Optional<User>> fun getCurrent(): Flowable<Optional<User>>
fun getByUsername(username: String): Flowable<Optional<User>> fun getByUsername(username: String): Flowable<Optional<User>>
......
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