Commit 772b55bd authored by Tiago Cunha's avatar Tiago Cunha

Almost done with room fragment

parent 8d9d67ea
......@@ -9,7 +9,7 @@ import chat.rocket.android.R;
import chat.rocket.android.fragment.server_config.LoginFragment;
import chat.rocket.android.fragment.server_config.RetryLoginFragment;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.persistence.realm.models.internal.Session;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmObjectObserver;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.android.service.ConnectivityManager;
......@@ -21,7 +21,7 @@ public class LoginActivity extends AbstractFragmentActivity {
public static final String KEY_HOSTNAME = "hostname";
private String hostname;
private RealmObjectObserver<Session> sessionObserver;
private RealmObjectObserver<RealmSession> sessionObserver;
@Override
protected int getLayoutContainerForFragment() {
......@@ -45,7 +45,7 @@ public class LoginActivity extends AbstractFragmentActivity {
}
sessionObserver = RealmStore.get(hostname)
.createObjectObserver(Session::queryDefaultSession)
.createObjectObserver(RealmSession::queryDefaultSession)
.setOnUpdateListener(this::onRenderServerConfigSession);
setContentView(R.layout.simple_screen);
......@@ -65,7 +65,7 @@ public class LoginActivity extends AbstractFragmentActivity {
super.onDestroy();
}
private void onRenderServerConfigSession(Session session) {
private void onRenderServerConfigSession(RealmSession session) {
if (session == null) {
return;
}
......
......@@ -17,27 +17,32 @@ import chat.rocket.android.fragment.chatroom.RoomFragment;
import chat.rocket.android.fragment.sidebar.SidebarMainFragment;
import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.core.interactors.CanCreateRoomInteractor;
import chat.rocket.persistence.realm.models.ddp.RealmRoom;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.models.internal.Session;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmListObserver;
import chat.rocket.persistence.realm.RealmObjectObserver;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.android.widget.RoomToolbar;
import chat.rocket.persistence.realm.repositories.RealmSessionRepository;
import chat.rocket.persistence.realm.repositories.RealmUserRepository;
import hugo.weaving.DebugLog;
/**
* Entry-point for Rocket.Chat.Android application.
*/
public class MainActivity extends AbstractAuthedActivity {
public class MainActivity extends AbstractAuthedActivity implements MainContract.View {
private RealmObjectObserver<Session> sessionObserver;
private RealmObjectObserver<RealmSession> sessionObserver;
private RealmListObserver<RealmRoom> unreadRoomSubscriptionObserver;
private boolean isForeground;
private StatusTicker statusTicker;
private MainContract.Presenter presenter;
@Override
protected int getLayoutContainerForFragment() {
return R.id.activity_main_container;
......@@ -70,11 +75,13 @@ public class MainActivity extends AbstractAuthedActivity {
protected void onResume() {
isForeground = true;
super.onResume();
presenter.bindView(this);
}
@Override
protected void onPause() {
isForeground = false;
presenter.release();
super.onPause();
}
......@@ -162,6 +169,16 @@ public class MainActivity extends AbstractAuthedActivity {
@Override
protected void onHostnameUpdated() {
super.onHostnameUpdated();
if (presenter != null) {
presenter.release();
}
CanCreateRoomInteractor interactor = new CanCreateRoomInteractor(
new RealmUserRepository(hostname),
new RealmSessionRepository(hostname)
);
presenter = new MainPresenter(interactor);
updateSessionObserver();
updateUnreadRoomSubscriptionObserver();
updateSidebarMainFragment();
......@@ -184,13 +201,13 @@ public class MainActivity extends AbstractAuthedActivity {
sessionObserver = realmHelper
.createObjectObserver(realm ->
Session.queryDefaultSession(realm)
.isNotNull(Session.TOKEN))
RealmSession.queryDefaultSession(realm)
.isNotNull(RealmSession.TOKEN))
.setOnUpdateListener(this::onSessionChanged);
sessionObserver.sub();
}
private void onSessionChanged(@Nullable Session session) {
private void onSessionChanged(@Nullable RealmSession session) {
if (session == null) {
if (isForeground) {
LaunchUtil.showLoginActivity(this, hostname);
......@@ -201,7 +218,7 @@ public class MainActivity extends AbstractAuthedActivity {
Snackbar.make(findViewById(getLayoutContainerForFragment()),
R.string.fragment_retry_login_error_title, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.fragment_retry_login_retry_title, view ->
Session.retryLogin(RealmStore.get(hostname))));
RealmSession.retryLogin(RealmStore.get(hostname))));
} else if (!session.isTokenVerified()) {
statusTicker.updateStatus(StatusTicker.STATUS_TOKEN_LOGIN,
Snackbar.make(findViewById(getLayoutContainerForFragment()),
......@@ -258,13 +275,7 @@ public class MainActivity extends AbstractAuthedActivity {
@Override
protected void onRoomIdUpdated() {
super.onRoomIdUpdated();
if (roomId != null && RoomFragment.canCreate(RealmStore.get(hostname))) {
showFragment(RoomFragment.create(hostname, roomId));
closeSidebarIfNeeded();
} else {
showFragment(new HomeFragment());
}
presenter.onOpenRoom(hostname, roomId);
}
@Override
......@@ -285,6 +296,17 @@ public class MainActivity extends AbstractAuthedActivity {
return closeSidebarIfNeeded() || super.onBackPress();
}
@Override
public void showHome() {
showFragment(new HomeFragment());
}
@Override
public void showRoom(String hostname, String roomId) {
showFragment(RoomFragment.create(hostname, roomId));
closeSidebarIfNeeded();
}
//TODO: consider this class to define in layouthelper for more complicated operation.
private static class StatusTicker {
public static final int STATUS_DISMISS = 0;
......
package chat.rocket.android.activity;
import chat.rocket.android.shared.BaseContract;
public interface MainContract {
interface View extends BaseContract.View {
void showHome();
void showRoom(String hostname, String roomId);
}
interface Presenter extends BaseContract.Presenter<View> {
void onOpenRoom(String hostname, String roomId);
}
}
package chat.rocket.android.activity;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.interactors.CanCreateRoomInteractor;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
public class MainPresenter extends BasePresenter<MainContract.View>
implements MainContract.Presenter {
private final CanCreateRoomInteractor canCreateRoomInteractor;
public MainPresenter(CanCreateRoomInteractor canCreateRoomInteractor) {
this.canCreateRoomInteractor = canCreateRoomInteractor;
}
@Override
public void onOpenRoom(String hostname, String roomId) {
final Subscription subscription = canCreateRoomInteractor.canCreate(roomId)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(allowed -> {
if (allowed) {
view.showRoom(hostname, roomId);
} else {
view.showHome();
}
});
addSubscription(subscription);
}
}
......@@ -17,7 +17,7 @@ import chat.rocket.core.SyncState;
import chat.rocket.persistence.realm.models.ddp.RealmMessage;
import chat.rocket.persistence.realm.models.ddp.RealmRoom;
import chat.rocket.persistence.realm.models.internal.MethodCall;
import chat.rocket.persistence.realm.models.internal.Session;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.android.service.DDPClientRef;
......@@ -44,7 +44,7 @@ public class MethodCallHelper {
* initialize with Context and hostname.
*/
public MethodCallHelper(Context context, String hostname) {
this.context = context;
this.context = context.getApplicationContext();
this.realmHelper = RealmStore.get(hostname);
ddpClientRef = null;
}
......@@ -126,8 +126,8 @@ public class MethodCallHelper {
private Task<Void> saveToken(Task<String> task) {
return realmHelper.executeTransaction(realm ->
realm.createOrUpdateObjectFromJson(Session.class, new JSONObject()
.put("sessionId", Session.DEFAULT_ID)
realm.createOrUpdateObjectFromJson(RealmSession.class, new JSONObject()
.put("sessionId", RealmSession.DEFAULT_ID)
.put("token", task.getResult())
.put("tokenVerified", true)
.put("error", JSONObject.NULL)
......@@ -191,7 +191,7 @@ public class MethodCallHelper {
.onSuccessTask(this::saveToken)
.continueWithTask(task -> {
if (task.isFaulted()) {
Session.logError(realmHelper, task.getError());
RealmSession.logError(realmHelper, task.getError());
}
return task;
});
......@@ -203,7 +203,7 @@ public class MethodCallHelper {
public Task<Void> logout() {
return call("logout", TIMEOUT_MS).onSuccessTask(task ->
realmHelper.executeTransaction(realm -> {
realm.delete(Session.class);
realm.delete(RealmSession.class);
return null;
}));
}
......
......@@ -4,7 +4,7 @@ import android.content.Context;
import chat.rocket.android.RocketChatCache;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.models.internal.Session;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmStore;
......@@ -35,8 +35,8 @@ public class DefaultCookieProvider implements CookieProvider {
final RealmUser user = realmHelper.executeTransactionForRead(realm ->
RealmUser.queryCurrentUser(realm).findFirst());
final Session session = realmHelper.executeTransactionForRead(realm ->
Session.queryDefaultSession(realm).findFirst());
final RealmSession session = realmHelper.executeTransactionForRead(realm ->
RealmSession.queryDefaultSession(realm).findFirst());
if (user == null || session == null) {
return "";
......
package chat.rocket.android.fragment.chatroom;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.util.List;
import chat.rocket.android.shared.BaseContract;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.Room;
public interface RoomContract {
interface View {
interface View extends BaseContract.View {
void render(Room room);
......@@ -19,22 +20,23 @@ public interface RoomContract {
void showUnreadCount(int count);
void showMessages(List<Message> messages);
}
interface Presenter {
void bindView(@NonNull View view);
void showMessageSendFailure(Message message);
}
void release();
interface Presenter extends BaseContract.Presenter<View> {
void loadMessages();
void loadMoreMessages();
void onMessageSelected(@Nullable Message message);
void sendMessage(String messageText);
void resendMessage(String messageId);
void resendMessage(Message message);
void deleteMessage(String messageId);
void deleteMessage(Message message);
void onUnreadCount();
......
......@@ -45,16 +45,11 @@ import chat.rocket.android.layouthelper.extra_action.upload.AudioUploadActionIte
import chat.rocket.android.layouthelper.extra_action.upload.ImageUploadActionItem;
import chat.rocket.android.layouthelper.extra_action.upload.VideoUploadActionItem;
import chat.rocket.android.log.RCLog;
import chat.rocket.core.SyncState;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.Room;
import chat.rocket.persistence.realm.models.ddp.RealmRoom;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.models.internal.Session;
import chat.rocket.persistence.realm.repositories.RealmMessageRepository;
import chat.rocket.persistence.realm.repositories.RealmRoomRepository;
import chat.rocket.persistence.realm.repositories.RealmUserRepository;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.android.layouthelper.chatroom.ModelListAdapter;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.android.service.ConnectivityManager;
......@@ -76,10 +71,7 @@ public class RoomFragment extends AbstractChatRoomFragment
private static final String ROOM_ID = "roomId";
private String hostname;
private RealmHelper realmHelper;
private String roomId;
private String userId;
private String token;
private LoadMoreScrollListener scrollListener;
private MessageFormManager messageFormManager;
private RecyclerViewAutoScrollManager autoScrollManager;
......@@ -95,14 +87,6 @@ public class RoomFragment extends AbstractChatRoomFragment
public RoomFragment() {
}
public static boolean canCreate(RealmHelper realmHelper) {
RealmUser currentUser = realmHelper.executeTransactionForRead(realm ->
RealmUser.queryCurrentUser(realm).findFirst());
Session session = realmHelper.executeTransactionForRead(realm ->
Session.queryDefaultSession(realm).findFirst());
return currentUser != null && session != null;
}
/**
* create fragment with roomId.
*/
......@@ -131,19 +115,11 @@ public class RoomFragment extends AbstractChatRoomFragment
new RealmRoomRepository(hostname),
new RealmMessageRepository(hostname),
new MethodCallHelper(getContext(), hostname),
ConnectivityManager.getInstance(getContext().getApplicationContext())
ConnectivityManager.getInstance(getContext())
);
realmHelper = RealmStore.get(hostname);
userId = realmHelper.executeTransactionForRead(realm ->
RealmUser.queryCurrentUser(realm).findFirst()).getId();
token = realmHelper.executeTransactionForRead(realm ->
Session.queryDefaultSession(realm).findFirst()).getToken();
if (savedInstanceState == null) {
initialRequest();
presenter.loadMessages();
}
}
......@@ -155,7 +131,7 @@ public class RoomFragment extends AbstractChatRoomFragment
@Override
protected void onSetupView() {
RecyclerView listView = (RecyclerView) rootView.findViewById(R.id.recyclerview);
adapter = new MessageListAdapter(getContext(), hostname, userId, token);
adapter = new MessageListAdapter(getContext(), hostname);
listView.setAdapter(adapter);
adapter.setOnItemClickListener(this);
......@@ -175,7 +151,7 @@ public class RoomFragment extends AbstractChatRoomFragment
scrollListener = new LoadMoreScrollListener(layoutManager, 40) {
@Override
public void requestMoreItem() {
loadMoreRequest();
presenter.loadMoreMessages();
}
};
listView.addOnScrollListener(scrollListener);
......@@ -237,20 +213,7 @@ public class RoomFragment extends AbstractChatRoomFragment
@Override
public void onItemClick(PairedMessage pairedMessage) {
if (pairedMessage.target != null) {
final int syncState = pairedMessage.target.getSyncState();
if (syncState == SyncState.FAILED) {
final String messageId = pairedMessage.target.getId();
new AlertDialog.Builder(getContext())
.setPositiveButton(R.string.resend,
(dialog, which) -> presenter.resendMessage(messageId))
.setNegativeButton(android.R.string.cancel, null)
.setNeutralButton(R.string.discard,
(dialog, which) -> presenter.deleteMessage(messageId))
.show();
}
}
presenter.onMessageSelected(pairedMessage.target);
}
private void setupSideMenu() {
......@@ -311,44 +274,16 @@ public class RoomFragment extends AbstractChatRoomFragment
}
private void uploadFile(Uri uri) {
String uplId = new FileUploadHelper(getContext(), realmHelper)
String uplId = new FileUploadHelper(getContext(), RealmStore.get(hostname))
.requestUploading(roomId, uri);
if (!TextUtils.isEmpty(uplId)) {
FileUploadProgressDialogFragment.create(hostname, roomId, uplId)
.show(getFragmentManager(), FileUploadProgressDialogFragment.class.getSimpleName());
.show(getFragmentManager(), "FileUploadProgressDialogFragment");
} else {
// show error.
}
}
private void onRenderRoom(Room room) {
String type = room.getType();
if (RealmRoom.TYPE_CHANNEL.equals(type)) {
setToolbarRoomIcon(R.drawable.ic_hashtag_gray_24dp);
} else if (RealmRoom.TYPE_PRIVATE.equals(type)) {
setToolbarRoomIcon(R.drawable.ic_lock_gray_24dp);
} else if (RealmRoom.TYPE_DIRECT_MESSAGE.equals(type)) {
setToolbarRoomIcon(R.drawable.ic_at_gray_24dp);
} else {
setToolbarRoomIcon(0);
}
setToolbarTitle(room.getName());
boolean unreadMessageExists = room.isAlert();
if (newMessageIndicatorManager != null && previousUnreadMessageExists && !unreadMessageExists) {
newMessageIndicatorManager.reset();
}
previousUnreadMessageExists = unreadMessageExists;
}
private void initialRequest() {
presenter.loadMessages();
}
private void loadMoreRequest() {
presenter.loadMoreMessages();
}
private void markAsReadIfNeeded() {
presenter.onMarkAsRead();
}
......@@ -445,7 +380,23 @@ public class RoomFragment extends AbstractChatRoomFragment
@Override
public void render(Room room) {
onRenderRoom(room);
String type = room.getType();
if (Room.TYPE_CHANNEL.equals(type)) {
setToolbarRoomIcon(R.drawable.ic_hashtag_gray_24dp);
} else if (Room.TYPE_PRIVATE.equals(type)) {
setToolbarRoomIcon(R.drawable.ic_lock_gray_24dp);
} else if (Room.TYPE_DIRECT_MESSAGE.equals(type)) {
setToolbarRoomIcon(R.drawable.ic_at_gray_24dp);
} else {
setToolbarRoomIcon(0);
}
setToolbarTitle(room.getName());
boolean unreadMessageExists = room.isAlert();
if (newMessageIndicatorManager != null && previousUnreadMessageExists && !unreadMessageExists) {
newMessageIndicatorManager.reset();
}
previousUnreadMessageExists = unreadMessageExists;
}
@Override
......@@ -477,4 +428,15 @@ public class RoomFragment extends AbstractChatRoomFragment
public void showMessages(List<Message> messages) {
adapter.updateData(messages);
}
@Override
public void showMessageSendFailure(Message message) {
new AlertDialog.Builder(getContext())
.setPositiveButton(R.string.resend,
(dialog, which) -> presenter.resendMessage(message))
.setNegativeButton(android.R.string.cancel, null)
.setNeutralButton(R.string.discard,
(dialog, which) -> presenter.deleteMessage(message))
.show();
}
}
package chat.rocket.android.fragment.chatroom;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.Pair;
import java.util.UUID;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.SyncState;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.RoomHistoryState;
......@@ -17,9 +19,9 @@ import chat.rocket.android.service.ConnectivityManagerApi;
import rx.Single;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.subscriptions.CompositeSubscription;
public class RoomPresenter implements RoomContract.Presenter {
public class RoomPresenter extends BasePresenter<RoomContract.View>
implements RoomContract.Presenter {
private final String roomId;
private final UserRepository userRepository;
......@@ -28,9 +30,6 @@ public class RoomPresenter implements RoomContract.Presenter {
private final MethodCallHelper methodCallHelper;
private final ConnectivityManagerApi connectivityManagerApi;
private CompositeSubscription compositeSubscription = new CompositeSubscription();
private RoomContract.View view;
public RoomPresenter(String roomId, UserRepository userRepository,
RoomRepository roomRepository,
MessageRepository messageRepository,
......@@ -46,19 +45,13 @@ public class RoomPresenter implements RoomContract.Presenter {
@Override
public void bindView(@NonNull RoomContract.View view) {
this.view = view;
super.bindView(view);
getRoomInfo();
getRoomHistoryStateInfo();
getMessages();
}
@Override
public void release() {
compositeSubscription.clear();
this.view = null;
}
@Override
public void loadMessages() {
RoomHistoryState roomHistoryState = RoomHistoryState.builder()
......@@ -79,7 +72,7 @@ public class RoomPresenter implements RoomContract.Presenter {
}
});
compositeSubscription.add(subscription);
addSubscription(subscription);
}
@Override
......@@ -103,12 +96,23 @@ public class RoomPresenter implements RoomContract.Presenter {
}
});
compositeSubscription.add(subscription);
addSubscription(subscription);
}
@Override
public void onMessageSelected(@Nullable Message message) {
if (message == null) {
return;
}
if (message.getSyncState() == SyncState.FAILED) {
view.showMessageSendFailure(message);
}
}
@Override
public void sendMessage(String messageText) {
final Subscription subscription = userRepository.getCurrentUser()
final Subscription subscription = userRepository.getCurrent()
.filter(user -> user != null)
.first()
.toSingle()
......@@ -133,36 +137,34 @@ public class RoomPresenter implements RoomContract.Presenter {
}
});
compositeSubscription.add(subscription);
addSubscription(subscription);
}
@Override
public void resendMessage(String messageId) {
final Subscription subscription = messageRepository.getById(messageId)
.map(message -> message.withSyncState(SyncState.NOT_SYNCED))
.flatMap(message -> messageRepository.resend(message))
public void resendMessage(Message message) {
final Subscription subscription = messageRepository.resend(
message.withSyncState(SyncState.NOT_SYNCED))
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
compositeSubscription.add(subscription);
addSubscription(subscription);
}
@Override
public void deleteMessage(String messageId) {
final Subscription subscription = messageRepository.getById(messageId)
.flatMap(message -> messageRepository.delete(message))
public void deleteMessage(Message message) {
final Subscription subscription = messageRepository.delete(message)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
compositeSubscription.add(subscription);
addSubscription(subscription);
}
@Override
public void onUnreadCount() {
final Subscription subscription = Single.zip(
userRepository.getCurrentUser()
userRepository.getCurrent()
.filter(user -> user != null)
.first()
.toSingle(),
......@@ -179,7 +181,7 @@ public class RoomPresenter implements RoomContract.Presenter {
count -> view.showUnreadCount(count)
);
compositeSubscription.add(subscription);
addSubscription(subscription);
}
@Override
......@@ -194,7 +196,7 @@ public class RoomPresenter implements RoomContract.Presenter {
.continueWith(new LogcatIfError())
);
compositeSubscription.add(subscription);
addSubscription(subscription);
}
private void getRoomInfo() {
......@@ -206,7 +208,7 @@ public class RoomPresenter implements RoomContract.Presenter {
room -> view.render(room)
);
compositeSubscription.add(subscription);
addSubscription(subscription);
}
private void getRoomHistoryStateInfo() {
......@@ -224,7 +226,7 @@ public class RoomPresenter implements RoomContract.Presenter {
}
);
compositeSubscription.add(subscription);
addSubscription(subscription);
}
private void getMessages() {
......@@ -235,6 +237,6 @@ public class RoomPresenter implements RoomContract.Presenter {
.observeOn(AndroidSchedulers.mainThread())
.subscribe(messages -> view.showMessages(messages));
compositeSubscription.add(subscription);
addSubscription(subscription);
}
}
......@@ -8,7 +8,7 @@ import android.widget.TextView;
import chat.rocket.android.R;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.persistence.realm.models.internal.Session;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmObjectObserver;
import chat.rocket.persistence.realm.RealmStore;
......@@ -16,7 +16,7 @@ import chat.rocket.persistence.realm.RealmStore;
* Login screen.
*/
public class RetryLoginFragment extends AbstractServerConfigFragment {
private RealmObjectObserver<Session> sessionObserver;
private RealmObjectObserver<RealmSession> sessionObserver;
@Override
protected int getLayout() {
......@@ -27,7 +27,7 @@ public class RetryLoginFragment extends AbstractServerConfigFragment {
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sessionObserver = RealmStore.get(hostname)
.createObjectObserver(Session::queryDefaultSession)
.createObjectObserver(RealmSession::queryDefaultSession)
.setOnUpdateListener(this::onRenderServerConfigSession);
}
......@@ -35,7 +35,7 @@ public class RetryLoginFragment extends AbstractServerConfigFragment {
protected void onSetupView() {
}
private void onRenderServerConfigSession(Session session) {
private void onRenderServerConfigSession(RealmSession session) {
if (session == null) {
return;
}
......
package chat.rocket.android.fragment.sidebar;
import android.support.annotation.NonNull;
import java.util.List;
import chat.rocket.android.shared.BaseContract;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.User;
public interface SidebarMainContract {
interface View {
interface View extends BaseContract.View {
void showScreen();
......@@ -19,10 +18,7 @@ public interface SidebarMainContract {
void showUser(User user);
}
interface Presenter {
void bindView(@NonNull View view);
void release();
interface Presenter extends BaseContract.Presenter<View> {
void onUserOnline();
......
......@@ -6,24 +6,21 @@ import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.models.User;
import chat.rocket.core.repositories.RoomRepository;
import chat.rocket.core.repositories.UserRepository;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.subscriptions.CompositeSubscription;
public class SidebarMainPresenter implements SidebarMainContract.Presenter {
public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View>
implements SidebarMainContract.Presenter {
private final String hostname;
private final RoomRepository roomRepository;
private final UserRepository userRepository;
private final MethodCallHelper methodCallHelper;
private SidebarMainContract.View view;
private CompositeSubscription compositeSubscription = new CompositeSubscription();
public SidebarMainPresenter(String hostname, RoomRepository roomRepository,
UserRepository userRepository, MethodCallHelper methodCallHelper) {
this.hostname = hostname;
......@@ -34,7 +31,7 @@ public class SidebarMainPresenter implements SidebarMainContract.Presenter {
@Override
public void bindView(@NonNull SidebarMainContract.View view) {
this.view = view;
super.bindView(view);
if (TextUtils.isEmpty(hostname)) {
view.showEmptyScreen();
......@@ -47,12 +44,6 @@ public class SidebarMainPresenter implements SidebarMainContract.Presenter {
subscribeToUser();
}
@Override
public void release() {
compositeSubscription.clear();
view = null;
}
@Override
public void onUserOnline() {
updateCurrentUserStatus(User.STATUS_ONLINE);
......@@ -89,17 +80,17 @@ public class SidebarMainPresenter implements SidebarMainContract.Presenter {
rooms -> view.showRoomList(rooms)
);
compositeSubscription.add(subscription);
addSubscription(subscription);
}
private void subscribeToUser() {
final Subscription subscription = userRepository.getCurrentUser()
final Subscription subscription = userRepository.getCurrent()
.distinctUntilChanged()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(user -> view.showUser(user));
compositeSubscription.add(subscription);
addSubscription(subscription);
}
private void updateCurrentUserStatus(String status) {
......
......@@ -17,15 +17,13 @@ public abstract class AbstractMessageViewHolder extends ModelViewHolder<PairedMe
protected final TextView timestamp;
protected final View userAndTimeContainer;
protected final String hostname;
protected final String userId;
protected final String token;
protected final View newDayContainer;
protected final TextView newDayText;
/**
* constructor WITH hostname.
*/
public AbstractMessageViewHolder(View itemView, String hostname, String userId, String token) {
public AbstractMessageViewHolder(View itemView, String hostname) {
super(itemView);
avatar = (RocketChatAvatar) itemView.findViewById(R.id.user_avatar);
username = (TextView) itemView.findViewById(R.id.username);
......@@ -35,8 +33,6 @@ public abstract class AbstractMessageViewHolder extends ModelViewHolder<PairedMe
newDayContainer = itemView.findViewById(R.id.newday_container);
newDayText = (TextView) itemView.findViewById(R.id.newday_text);
this.hostname = hostname;
this.userId = userId;
this.token = token;
}
/**
......
......@@ -23,16 +23,12 @@ public class MessageListAdapter
private static final int VIEW_TYPE_SYSTEM_MESSAGE = 2;
private final String hostname;
private final String userId;
private final String token;
private boolean hasNext;
private boolean isLoaded;
public MessageListAdapter(Context context, String hostname, String userId, String token) {
public MessageListAdapter(Context context, String hostname) {
super(context);
this.hostname = hostname;
this.userId = userId;
this.token = token;
}
/**
......@@ -86,11 +82,11 @@ public class MessageListAdapter
protected AbstractMessageViewHolder onCreateRealmModelViewHolder(int viewType, View itemView) {
switch (viewType) {
case VIEW_TYPE_NORMAL_MESSAGE:
return new MessageNormalViewHolder(itemView, hostname, userId, token);
return new MessageNormalViewHolder(itemView, hostname);
case VIEW_TYPE_SYSTEM_MESSAGE:
return new MessageSystemViewHolder(itemView, hostname, userId, token);
return new MessageSystemViewHolder(itemView, hostname);
default:
return new AbstractMessageViewHolder(itemView, hostname, userId, token) {
return new AbstractMessageViewHolder(itemView, hostname) {
@Override
protected void bindMessage(PairedMessage pairedMessage) {
}
......
......@@ -19,8 +19,8 @@ public class MessageNormalViewHolder extends AbstractMessageViewHolder {
/**
* constructor WITH hostname.
*/
public MessageNormalViewHolder(View itemView, String hostname, String userId, String token) {
super(itemView, hostname, userId, token);
public MessageNormalViewHolder(View itemView, String hostname) {
super(itemView, hostname);
body = (RocketChatMessageLayout) itemView.findViewById(R.id.message_body);
urls = (RocketChatMessageUrlsLayout) itemView.findViewById(R.id.message_urls);
attachments =
......@@ -35,6 +35,6 @@ public class MessageNormalViewHolder extends AbstractMessageViewHolder {
.timestampInto(timestamp)
.bodyInto(body)
.urlsInto(urls)
.attachmentsInto(attachments, hostname, userId, token);
.attachmentsInto(attachments, hostname);
}
}
......@@ -15,8 +15,8 @@ public class MessageSystemViewHolder extends AbstractMessageViewHolder {
/**
* constructor WITH hostname.
*/
public MessageSystemViewHolder(View itemView, String hostname, String userId, String token) {
super(itemView, hostname, userId, token);
public MessageSystemViewHolder(View itemView, String hostname) {
super(itemView, hostname);
body = (TextView) itemView.findViewById(R.id.message_body);
}
......
......@@ -121,7 +121,7 @@ public class MessageRenderer extends AbstractRenderer<Message> {
* show urls in RocketChatMessageUrlsLayout.
*/
public MessageRenderer attachmentsInto(RocketChatMessageAttachmentsLayout attachmentsLayout,
String hostname, String userId, String token) {
String hostname) {
if (!shouldHandle(attachmentsLayout)) {
return this;
}
......
......@@ -43,7 +43,7 @@ import rx.subjects.PublishSubject;
/*package*/ RealmBasedConnectivityManager setContext(Context appContext) {
this.appContext = appContext;
this.appContext = appContext.getApplicationContext();
return this;
}
......@@ -67,7 +67,8 @@ import rx.subjects.PublishSubject;
public void ensureConnections() {
for (String hostname : serverConnectivityList.keySet()) {
connectToServerIfNeeded(hostname, true/* force connect */)
.subscribe(_val -> { }, RCLog::e);
.subscribe(_val -> {
}, RCLog::e);
}
}
......@@ -79,7 +80,8 @@ import rx.subjects.PublishSubject;
serverConnectivityList.put(hostname, ServerConnectivity.STATE_DISCONNECTED);
}
connectToServerIfNeeded(hostname, false)
.subscribe(_val -> { }, RCLog::e);
.subscribe(_val -> {
}, RCLog::e);
}
@Override
......@@ -87,7 +89,8 @@ import rx.subjects.PublishSubject;
RealmBasedServerInfo.remove(hostname);
if (serverConnectivityList.containsKey(hostname)) {
disconnectFromServerIfNeeded(hostname)
.subscribe(_val -> { }, RCLog::e);
.subscribe(_val -> {
}, RCLog::e);
}
}
......@@ -187,7 +190,8 @@ import rx.subjects.PublishSubject;
.filter(serverConnectivity -> hostname.equals(serverConnectivity.hostname))
.map(serverConnectivity -> serverConnectivity.state)
.filter(state ->
state == ServerConnectivity.STATE_CONNECTED || state == ServerConnectivity.STATE_DISCONNECTED)
state == ServerConnectivity.STATE_CONNECTED
|| state == ServerConnectivity.STATE_DISCONNECTED)
.first()
.toSingle()
.flatMap(state ->
......
......@@ -15,7 +15,7 @@ import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.log.RCLog;
import chat.rocket.core.models.ServerInfo;
import chat.rocket.persistence.realm.models.internal.Session;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.android.service.ddp.base.ActiveUsersSubscriber;
......@@ -127,7 +127,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
private void forceInvalidateTokens() {
realmHelper.executeTransaction(realm -> {
Session session = Session.queryDefaultSession(realm).findFirst();
RealmSession session = RealmSession.queryDefaultSession(realm).findFirst();
if (session != null
&& !TextUtils.isEmpty(session.getToken())
&& (session.isTokenVerified() || !TextUtils.isEmpty(session.getError()))) {
......@@ -240,10 +240,10 @@ public class RocketChatWebSocketThread extends HandlerThread {
});
return realmHelper.executeTransaction(realm -> {
Session sessionObj = Session.queryDefaultSession(realm).findFirst();
RealmSession sessionObj = RealmSession.queryDefaultSession(realm).findFirst();
if (sessionObj == null) {
realm.createOrUpdateObjectFromJson(Session.class,
new JSONObject().put(Session.ID, Session.DEFAULT_ID));
realm.createOrUpdateObjectFromJson(RealmSession.class,
new JSONObject().put(RealmSession.ID, RealmSession.DEFAULT_ID));
} else {
// invalidate login token.
if (!TextUtils.isEmpty(sessionObj.getToken()) && sessionObj.isTokenVerified()) {
......
......@@ -16,7 +16,7 @@ import chat.rocket.android.log.RCLog;
import chat.rocket.core.SyncState;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.models.internal.FileUploading;
import chat.rocket.persistence.realm.models.internal.Session;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.android.service.DDPClientRef;
import okhttp3.MediaType;
......@@ -94,8 +94,8 @@ public class FileUploadingWithUfsObserver extends AbstractModelObserver<FileUplo
RealmUser currentUser = realmHelper.executeTransactionForRead(realm ->
RealmUser.queryCurrentUser(realm).findFirst());
Session session = realmHelper.executeTransactionForRead(realm ->
Session.queryDefaultSession(realm).findFirst());
RealmSession session = realmHelper.executeTransactionForRead(realm ->
RealmSession.queryDefaultSession(realm).findFirst());
if (currentUser == null || session == null) {
return;
}
......
......@@ -11,7 +11,7 @@ import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.persistence.realm.models.internal.GetUsersOfRoomsProcedure;
import chat.rocket.persistence.realm.models.internal.LoadMessageProcedure;
import chat.rocket.persistence.realm.models.internal.MethodCall;
import chat.rocket.persistence.realm.models.internal.Session;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.android.service.DDPClientRef;
import chat.rocket.android.service.internal.StreamRoomMessageManager;
......@@ -20,7 +20,7 @@ import hugo.weaving.DebugLog;
/**
* Observes user is logged into server.
*/
public class SessionObserver extends AbstractModelObserver<Session> {
public class SessionObserver extends AbstractModelObserver<RealmSession> {
private final StreamRoomMessageManager streamNotifyMessage;
private final RaixPushHelper pushHelper;
private int count;
......@@ -38,16 +38,16 @@ public class SessionObserver extends AbstractModelObserver<Session> {
}
@Override
public RealmResults<Session> queryItems(Realm realm) {
return realm.where(Session.class)
.isNotNull(Session.TOKEN)
.equalTo(Session.TOKEN_VERIFIED, true)
.isNull(Session.ERROR)
public RealmResults<RealmSession> queryItems(Realm realm) {
return realm.where(RealmSession.class)
.isNotNull(RealmSession.TOKEN)
.equalTo(RealmSession.TOKEN_VERIFIED, true)
.isNull(RealmSession.ERROR)
.findAll();
}
@Override
public void onUpdateResults(List<Session> results) {
public void onUpdateResults(List<RealmSession> results) {
int origCount = count;
count = results.size();
if (origCount > 0 && count > 0) {
......
......@@ -7,11 +7,11 @@ import io.realm.RealmResults;
import java.util.List;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.persistence.realm.models.internal.Session;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.android.service.DDPClientRef;
public class TokenLoginObserver extends AbstractModelObserver<Session> {
public class TokenLoginObserver extends AbstractModelObserver<RealmSession> {
private final MethodCallHelper methodCall;
......@@ -22,21 +22,21 @@ public class TokenLoginObserver extends AbstractModelObserver<Session> {
}
@Override
public RealmResults<Session> queryItems(Realm realm) {
return realm.where(Session.class)
.isNotNull(Session.TOKEN)
.equalTo(Session.TOKEN_VERIFIED, false)
.isNull(Session.ERROR)
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<Session> results) {
public void onUpdateResults(List<RealmSession> results) {
if (results.isEmpty()) {
return;
}
Session session = results.get(0);
RealmSession session = results.get(0);
methodCall.loginWithToken(session.getToken()).continueWith(new LogcatIfError());
}
}
package chat.rocket.android.shared;
import android.support.annotation.NonNull;
public interface BaseContract {
interface View {
}
interface Presenter<T extends View> {
void bindView(@NonNull T view);
void release();
}
}
package chat.rocket.android.shared;
import android.support.annotation.NonNull;
import rx.Subscription;
import rx.subscriptions.CompositeSubscription;
public abstract class BasePresenter<T extends BaseContract.View>
implements BaseContract.Presenter<T> {
protected T view;
private CompositeSubscription compositeSubscription = new CompositeSubscription();
@Override
public void bindView(@NonNull T view) {
this.view = view;
}
@Override
public void release() {
compositeSubscription.clear();
view = null;
}
protected void addSubscription(Subscription subscription) {
compositeSubscription.add(subscription);
}
}
......@@ -7,6 +7,7 @@ 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;
......@@ -14,7 +15,7 @@ import hugo.weaving.DebugLog;
/**
* Login session info.
*/
public class Session extends RealmObject {
public class RealmSession extends RealmObject {
@SuppressWarnings({"PMD.ShortVariable"})
public static final String ID = "sessionId";
......@@ -30,8 +31,8 @@ public class Session extends RealmObject {
private boolean tokenVerified;
private String error;
public static RealmQuery<Session> queryDefaultSession(Realm realm) {
return realm.where(Session.class).equalTo(ID, Session.DEFAULT_ID);
public static RealmQuery<RealmSession> queryDefaultSession(Realm realm) {
return realm.where(RealmSession.class).equalTo(ID, RealmSession.DEFAULT_ID);
}
/**
......@@ -42,13 +43,13 @@ public class Session extends RealmObject {
String errString = exception.getMessage();
if (!TextUtils.isEmpty(errString) && errString.contains(AUTH_ERROR_CODE)) {
realmHelper.executeTransaction(realm -> {
realm.delete(Session.class);
realm.delete(RealmSession.class);
return null;
}).continueWith(new LogcatIfError());
} else {
realmHelper.executeTransaction(
realm -> realm.createOrUpdateObjectFromJson(Session.class, new JSONObject()
.put(ID, Session.DEFAULT_ID)
realm -> realm.createOrUpdateObjectFromJson(RealmSession.class, new JSONObject()
.put(ID, RealmSession.DEFAULT_ID)
.put(TOKEN_VERIFIED, false)
.put(ERROR, errString)))
.continueWith(new LogcatIfError());
......@@ -60,13 +61,13 @@ public class Session extends RealmObject {
*/
@DebugLog
public static void retryLogin(RealmHelper realmHelper) {
final Session session = realmHelper.executeTransactionForRead(realm ->
final RealmSession session = realmHelper.executeTransactionForRead(realm ->
queryDefaultSession(realm).isNotNull(TOKEN).findFirst());
if (!session.isTokenVerified() || !TextUtils.isEmpty(session.getError())) {
realmHelper.executeTransaction(
realm -> realm.createOrUpdateObjectFromJson(Session.class, new JSONObject()
.put(ID, Session.DEFAULT_ID)
realm -> realm.createOrUpdateObjectFromJson(RealmSession.class, new JSONObject()
.put(ID, RealmSession.DEFAULT_ID)
.put(TOKEN_VERIFIED, false)
.put(ERROR, JSONObject.NULL)))
.continueWith(new LogcatIfError());
......@@ -104,4 +105,13 @@ public class Session extends RealmObject {
public void setError(String error) {
this.error = error;
}
public Session asSession() {
return Session.builder()
.setSessionId(sessionId)
.setToken(token)
.setTokenVerified(tokenVerified)
.setError(error)
.build();
}
}
package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import io.realm.Realm;
import chat.rocket.core.models.Session;
import chat.rocket.core.repositories.SessionRepository;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
public class RealmSessionRepository extends RealmRepository implements SessionRepository {
private final String hostname;
public RealmSessionRepository(String hostname) {
this.hostname = hostname;
}
@Override
public Observable<Session> getDefault() {
return Observable.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null) {
return Observable.just(null);
}
final RealmSession realmSession =
realm.where(RealmSession.class).equalTo(RealmSession.ID, RealmSession.DEFAULT_ID)
.findFirst();
if (realmSession == null) {
realm.close();
return Observable.just(null);
}
return realmSession
.<RealmSession>asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.filter(it -> it != null && it.isLoaded() && it.isValid())
.map(RealmSession::asSession);
});
}
}
......@@ -19,7 +19,7 @@ public class RealmUserRepository extends RealmRepository implements UserReposito
}
@Override
public Observable<User> getCurrentUser() {
public Observable<User> getCurrent() {
return Observable.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
......
plugins {
id "net.ltgt.apt" version "0.9"
id "me.tatarka.retrolambda" version "3.5.0"
}
apply plugin: 'idea'
......@@ -17,5 +18,5 @@ dependencies {
apt 'com.gabrielittner.auto.value:auto-value-with:1.0.0'
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
package chat.rocket.core.interactors;
import chat.rocket.core.repositories.SessionRepository;
import chat.rocket.core.repositories.UserRepository;
import rx.Observable;
import rx.Single;
public class CanCreateRoomInteractor {
private final UserRepository userRepository;
private final SessionRepository sessionRepository;
public CanCreateRoomInteractor(UserRepository userRepository,
SessionRepository sessionRepository) {
this.userRepository = userRepository;
this.sessionRepository = sessionRepository;
}
public Single<Boolean> canCreate(String roomId) {
return Observable.zip(
userRepository.getCurrent(),
sessionRepository.getDefault(),
Observable.just(roomId),
(user, session, room) -> user != null && session != null && room != null
)
.first()
.toSingle();
}
}
package chat.rocket.core.models;
import com.google.auto.value.AutoValue;
import javax.annotation.Nullable;
@AutoValue
public abstract class Session {
public abstract int getSessionId();
@Nullable
public abstract String getToken();
public abstract boolean isTokenVerified();
@Nullable
public abstract String getError();
public static Builder builder() {
return new AutoValue_Session.Builder();
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setSessionId(int sessionId);
public abstract Builder setToken(String token);
public abstract Builder setTokenVerified(boolean tokenVerified);
public abstract Builder setError(String error);
public abstract Session build();
}
}
package chat.rocket.core.repositories;
import chat.rocket.core.models.Session;
import rx.Observable;
public interface SessionRepository {
Observable<Session> getDefault();
}
......@@ -5,5 +5,5 @@ import rx.Observable;
public interface UserRepository {
Observable<User> getCurrentUser();
Observable<User> getCurrent();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment