Commit 4ab44fd0 authored by Tiago Cunha's avatar Tiago Cunha

More stuff

parent 3eb9b754
...@@ -15,15 +15,12 @@ import chat.rocket.android.fragment.chatroom.HomeFragment; ...@@ -15,15 +15,12 @@ import chat.rocket.android.fragment.chatroom.HomeFragment;
import chat.rocket.android.fragment.chatroom.RoomFragment; import chat.rocket.android.fragment.chatroom.RoomFragment;
import chat.rocket.android.fragment.sidebar.SidebarMainFragment; import chat.rocket.android.fragment.sidebar.SidebarMainFragment;
import chat.rocket.android.helper.LogcatIfError; import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.core.interactors.CanCreateRoomInteractor; import chat.rocket.core.interactors.CanCreateRoomInteractor;
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.persistence.realm.models.ddp.RealmUser; import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.models.internal.RealmSession; import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmObjectObserver; import chat.rocket.persistence.realm.RealmObjectObserver;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.android.service.ConnectivityManager; import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.android.widget.RoomToolbar; import chat.rocket.android.widget.RoomToolbar;
import chat.rocket.persistence.realm.repositories.RealmRoomRepository; import chat.rocket.persistence.realm.repositories.RealmRoomRepository;
...@@ -37,7 +34,6 @@ import hugo.weaving.DebugLog; ...@@ -37,7 +34,6 @@ import hugo.weaving.DebugLog;
public class MainActivity extends AbstractAuthedActivity implements MainContract.View { public class MainActivity extends AbstractAuthedActivity implements MainContract.View {
private RealmObjectObserver<RealmSession> sessionObserver; private RealmObjectObserver<RealmSession> sessionObserver;
private boolean isForeground;
private StatusTicker statusTicker; private StatusTicker statusTicker;
private MainContract.Presenter presenter; private MainContract.Presenter presenter;
...@@ -72,7 +68,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract ...@@ -72,7 +68,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
@Override @Override
protected void onResume() { protected void onResume() {
isForeground = true;
super.onResume(); super.onResume();
if (presenter != null) { if (presenter != null) {
...@@ -82,8 +77,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract ...@@ -82,8 +77,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
@Override @Override
protected void onPause() { protected void onPause() {
isForeground = false;
if (presenter != null) { if (presenter != null) {
presenter.release(); presenter.release();
} }
...@@ -187,58 +180,19 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract ...@@ -187,58 +180,19 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
new SessionInteractor(new RealmSessionRepository(hostname)) new SessionInteractor(new RealmSessionRepository(hostname))
); );
SessionInteractor sessionInteractor = new SessionInteractor(
new RealmSessionRepository(hostname)
);
presenter = new MainPresenter( presenter = new MainPresenter(
roomInteractor, roomInteractor,
createRoomInteractor); createRoomInteractor,
sessionInteractor
);
updateSessionObserver();
updateSidebarMainFragment(); updateSidebarMainFragment();
} }
private void updateSessionObserver() {
if (sessionObserver != null) {
sessionObserver.unsub();
sessionObserver = null;
}
if (hostname == null) {
return;
}
RealmHelper realmHelper = RealmStore.get(hostname);
if (realmHelper == null) {
return;
}
sessionObserver = realmHelper
.createObjectObserver(realm ->
RealmSession.queryDefaultSession(realm)
.isNotNull(RealmSession.TOKEN))
.setOnUpdateListener(this::onSessionChanged);
sessionObserver.sub();
}
private void onSessionChanged(@Nullable RealmSession session) {
if (session == null) {
if (isForeground) {
LaunchUtil.showLoginActivity(this, hostname);
}
statusTicker.updateStatus(StatusTicker.STATUS_DISMISS, null);
} else if (!TextUtils.isEmpty(session.getError())) {
statusTicker.updateStatus(StatusTicker.STATUS_CONNECTION_ERROR,
Snackbar.make(findViewById(getLayoutContainerForFragment()),
R.string.fragment_retry_login_error_title, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.fragment_retry_login_retry_title, view ->
RealmSession.retryLogin(RealmStore.get(hostname))));
} else if (!session.isTokenVerified()) {
statusTicker.updateStatus(StatusTicker.STATUS_TOKEN_LOGIN,
Snackbar.make(findViewById(getLayoutContainerForFragment()),
R.string.server_config_activity_authenticating, Snackbar.LENGTH_INDEFINITE));
} else {
statusTicker.updateStatus(StatusTicker.STATUS_DISMISS, null);
}
}
private void updateSidebarMainFragment() { private void updateSidebarMainFragment() {
getSupportFragmentManager().beginTransaction() getSupportFragmentManager().beginTransaction()
.replace(R.id.sidebar_fragment_container, SidebarMainFragment.create(hostname)) .replace(R.id.sidebar_fragment_container, SidebarMainFragment.create(hostname))
...@@ -284,6 +238,33 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract ...@@ -284,6 +238,33 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
} }
} }
@Override
public void showLoginScreen() {
LaunchUtil.showLoginActivity(this, hostname);
statusTicker.updateStatus(StatusTicker.STATUS_DISMISS, null);
}
@Override
public void showConnectionError() {
statusTicker.updateStatus(StatusTicker.STATUS_CONNECTION_ERROR,
Snackbar.make(findViewById(getLayoutContainerForFragment()),
R.string.fragment_retry_login_error_title, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.fragment_retry_login_retry_title, view ->
presenter.onRetryLogin()));
}
@Override
public void showConnecting() {
statusTicker.updateStatus(StatusTicker.STATUS_TOKEN_LOGIN,
Snackbar.make(findViewById(getLayoutContainerForFragment()),
R.string.server_config_activity_authenticating, Snackbar.LENGTH_INDEFINITE));
}
@Override
public void showConnectionOk() {
statusTicker.updateStatus(StatusTicker.STATUS_DISMISS, null);
}
//TODO: consider this class to define in layouthelper for more complicated operation. //TODO: consider this class to define in layouthelper for more complicated operation.
private static class StatusTicker { private static class StatusTicker {
public static final int STATUS_DISMISS = 0; public static final int STATUS_DISMISS = 0;
......
...@@ -11,10 +11,20 @@ public interface MainContract { ...@@ -11,10 +11,20 @@ public interface MainContract {
void showRoom(String hostname, String roomId); void showRoom(String hostname, String roomId);
void showUnreadCount(int roomsCount, int mentionsCount); void showUnreadCount(int roomsCount, int mentionsCount);
void showLoginScreen();
void showConnectionError();
void showConnecting();
void showConnectionOk();
} }
interface Presenter extends BaseContract.Presenter<View> { interface Presenter extends BaseContract.Presenter<View> {
void onOpenRoom(String hostname, String roomId); void onOpenRoom(String hostname, String roomId);
void onRetryLogin();
} }
} }
...@@ -7,6 +7,7 @@ import chat.rocket.android.BackgroundLooper; ...@@ -7,6 +7,7 @@ import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.shared.BasePresenter; import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.interactors.CanCreateRoomInteractor; import chat.rocket.core.interactors.CanCreateRoomInteractor;
import chat.rocket.core.interactors.RoomInteractor; import chat.rocket.core.interactors.RoomInteractor;
import chat.rocket.core.interactors.SessionInteractor;
import rx.Observable; import rx.Observable;
import rx.Subscription; import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers; import rx.android.schedulers.AndroidSchedulers;
...@@ -16,11 +17,14 @@ public class MainPresenter extends BasePresenter<MainContract.View> ...@@ -16,11 +17,14 @@ public class MainPresenter extends BasePresenter<MainContract.View>
private final CanCreateRoomInteractor canCreateRoomInteractor; private final CanCreateRoomInteractor canCreateRoomInteractor;
private final RoomInteractor roomInteractor; private final RoomInteractor roomInteractor;
private final SessionInteractor sessionInteractor;
public MainPresenter(RoomInteractor roomInteractor, public MainPresenter(RoomInteractor roomInteractor,
CanCreateRoomInteractor canCreateRoomInteractor) { CanCreateRoomInteractor canCreateRoomInteractor,
SessionInteractor sessionInteractor) {
this.roomInteractor = roomInteractor; this.roomInteractor = roomInteractor;
this.canCreateRoomInteractor = canCreateRoomInteractor; this.canCreateRoomInteractor = canCreateRoomInteractor;
this.sessionInteractor = sessionInteractor;
} }
@Override @Override
...@@ -28,6 +32,31 @@ public class MainPresenter extends BasePresenter<MainContract.View> ...@@ -28,6 +32,31 @@ public class MainPresenter extends BasePresenter<MainContract.View>
super.bindView(view); super.bindView(view);
subscribeToUnreadCount(); subscribeToUnreadCount();
subscribeToSession();
}
@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);
}
@Override
public void onRetryLogin() {
final Subscription subscription = sessionInteractor.retryLogin()
.subscribe();
addSubscription(subscription);
} }
private void subscribeToUnreadCount() { private void subscribeToUnreadCount() {
...@@ -43,17 +72,28 @@ public class MainPresenter extends BasePresenter<MainContract.View> ...@@ -43,17 +72,28 @@ public class MainPresenter extends BasePresenter<MainContract.View>
addSubscription(subscription); addSubscription(subscription);
} }
@Override private void subscribeToSession() {
public void onOpenRoom(String hostname, String roomId) { final Subscription subscription = sessionInteractor.getDefault()
final Subscription subscription = canCreateRoomInteractor.canCreate(roomId)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get())) .subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(allowed -> { .subscribe(session -> {
if (allowed) { if (session == null || session.getToken() == null) {
view.showRoom(hostname, roomId); view.showLoginScreen();
} else { return;
view.showHome(); }
String error = session.getError();
if (error != null && error.length() != 0) {
view.showConnectionError();
return;
}
if (!session.isTokenVerified()) {
view.showConnecting();
return;
} }
view.showConnectionOk();
}); });
addSubscription(subscription); addSubscription(subscription);
......
...@@ -56,24 +56,6 @@ public class RealmSession extends RealmObject { ...@@ -56,24 +56,6 @@ public class RealmSession extends RealmObject {
} }
} }
/**
* retry authentication.
*/
@DebugLog
public static void retryLogin(RealmHelper realmHelper) {
final RealmSession session = realmHelper.executeTransactionForRead(realm ->
queryDefaultSession(realm).isNotNull(TOKEN).findFirst());
if (!session.isTokenVerified() || !TextUtils.isEmpty(session.getError())) {
realmHelper.executeTransaction(
realm -> realm.createOrUpdateObjectFromJson(RealmSession.class, new JSONObject()
.put(ID, RealmSession.DEFAULT_ID)
.put(TOKEN_VERIFIED, false)
.put(ERROR, JSONObject.NULL)))
.continueWith(new LogcatIfError());
}
}
public int getSessionId() { public int getSessionId() {
return sessionId; return sessionId;
} }
......
...@@ -8,6 +8,7 @@ import chat.rocket.core.repositories.SessionRepository; ...@@ -8,6 +8,7 @@ import chat.rocket.core.repositories.SessionRepository;
import chat.rocket.persistence.realm.RealmStore; import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.internal.RealmSession; import chat.rocket.persistence.realm.models.internal.RealmSession;
import rx.Observable; import rx.Observable;
import rx.Single;
import rx.android.schedulers.AndroidSchedulers; import rx.android.schedulers.AndroidSchedulers;
public class RealmSessionRepository extends RealmRepository implements SessionRepository { public class RealmSessionRepository extends RealmRepository implements SessionRepository {
...@@ -43,4 +44,43 @@ public class RealmSessionRepository extends RealmRepository implements SessionRe ...@@ -43,4 +44,43 @@ public class RealmSessionRepository extends RealmRepository implements SessionRe
}); });
}); });
} }
@Override
public Single<Boolean> save(Session session) {
return Single.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null || looper == null) {
return Single.just(null);
}
RealmSession realmSession = realm.where(RealmSession.class)
.equalTo(RealmSession.ID, session.getSessionId())
.findFirst();
if (realmSession == null) {
realmSession = new RealmSession();
} else {
realmSession = realm.copyFromRealm(realmSession);
}
realmSession.setSessionId(session.getSessionId());
realmSession.setToken(session.getToken());
realmSession.setTokenVerified(session.isTokenVerified());
realmSession.setError(session.getError());
realm.beginTransaction();
return realm.copyToRealmOrUpdate(realmSession)
.asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.filter(it -> it != null && it.isLoaded() && it.isValid())
.first()
.doOnNext(it -> realm.commitTransaction())
.toSingle()
.map(realmObject -> true);
});
}
} }
...@@ -3,6 +3,7 @@ package chat.rocket.core.interactors; ...@@ -3,6 +3,7 @@ package chat.rocket.core.interactors;
import chat.rocket.core.models.Session; import chat.rocket.core.models.Session;
import chat.rocket.core.repositories.SessionRepository; import chat.rocket.core.repositories.SessionRepository;
import rx.Observable; import rx.Observable;
import rx.Single;
public class SessionInteractor { public class SessionInteractor {
...@@ -23,6 +24,15 @@ public class SessionInteractor { ...@@ -23,6 +24,15 @@ public class SessionInteractor {
.map(this::getStateFrom); .map(this::getStateFrom);
} }
public Single<Boolean> retryLogin() {
return getDefault()
.filter(session -> session.getToken() != null
&& (!session.isTokenVerified() || session.getError() != null))
.map(session -> session.withTokenVerified(false).withError(null))
.toSingle()
.flatMap(sessionRepository::save);
}
private Session.State getStateFrom(Session session) { private Session.State getStateFrom(Session session) {
if (session == null) { if (session == null) {
return Session.State.UNAVAILABLE; return Session.State.UNAVAILABLE;
......
...@@ -19,6 +19,10 @@ public abstract class Session { ...@@ -19,6 +19,10 @@ public abstract class Session {
@Nullable @Nullable
public abstract String getError(); public abstract String getError();
public abstract Session withTokenVerified(boolean tokenVerified);
public abstract Session withError(String error);
public static Builder builder() { public static Builder builder() {
return new AutoValue_Session.Builder(); return new AutoValue_Session.Builder();
} }
......
...@@ -2,8 +2,11 @@ package chat.rocket.core.repositories; ...@@ -2,8 +2,11 @@ package chat.rocket.core.repositories;
import chat.rocket.core.models.Session; import chat.rocket.core.models.Session;
import rx.Observable; import rx.Observable;
import rx.Single;
public interface SessionRepository { public interface SessionRepository {
Observable<Session> getById(int id); Observable<Session> getById(int id);
Single<Boolean> save(Session session);
} }
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