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;
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.core.interactors.RoomInteractor;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.models.internal.RealmSession;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.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.RealmRoomRepository;
......@@ -37,7 +34,6 @@ import hugo.weaving.DebugLog;
public class MainActivity extends AbstractAuthedActivity implements MainContract.View {
private RealmObjectObserver<RealmSession> sessionObserver;
private boolean isForeground;
private StatusTicker statusTicker;
private MainContract.Presenter presenter;
......@@ -72,7 +68,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
@Override
protected void onResume() {
isForeground = true;
super.onResume();
if (presenter != null) {
......@@ -82,8 +77,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
@Override
protected void onPause() {
isForeground = false;
if (presenter != null) {
presenter.release();
}
......@@ -187,58 +180,19 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
new SessionInteractor(new RealmSessionRepository(hostname))
);
SessionInteractor sessionInteractor = new SessionInteractor(
new RealmSessionRepository(hostname)
);
presenter = new MainPresenter(
roomInteractor,
createRoomInteractor);
createRoomInteractor,
sessionInteractor
);
updateSessionObserver();
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() {
getSupportFragmentManager().beginTransaction()
.replace(R.id.sidebar_fragment_container, SidebarMainFragment.create(hostname))
......@@ -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.
private static class StatusTicker {
public static final int STATUS_DISMISS = 0;
......
......@@ -11,10 +11,20 @@ public interface MainContract {
void showRoom(String hostname, String roomId);
void showUnreadCount(int roomsCount, int mentionsCount);
void showLoginScreen();
void showConnectionError();
void showConnecting();
void showConnectionOk();
}
interface Presenter extends BaseContract.Presenter<View> {
void onOpenRoom(String hostname, String roomId);
void onRetryLogin();
}
}
......@@ -7,6 +7,7 @@ import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.interactors.CanCreateRoomInteractor;
import chat.rocket.core.interactors.RoomInteractor;
import chat.rocket.core.interactors.SessionInteractor;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
......@@ -16,11 +17,14 @@ public class MainPresenter extends BasePresenter<MainContract.View>
private final CanCreateRoomInteractor canCreateRoomInteractor;
private final RoomInteractor roomInteractor;
private final SessionInteractor sessionInteractor;
public MainPresenter(RoomInteractor roomInteractor,
CanCreateRoomInteractor canCreateRoomInteractor) {
CanCreateRoomInteractor canCreateRoomInteractor,
SessionInteractor sessionInteractor) {
this.roomInteractor = roomInteractor;
this.canCreateRoomInteractor = canCreateRoomInteractor;
this.sessionInteractor = sessionInteractor;
}
@Override
......@@ -28,6 +32,31 @@ public class MainPresenter extends BasePresenter<MainContract.View>
super.bindView(view);
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() {
......@@ -43,17 +72,28 @@ public class MainPresenter extends BasePresenter<MainContract.View>
addSubscription(subscription);
}
@Override
public void onOpenRoom(String hostname, String roomId) {
final Subscription subscription = canCreateRoomInteractor.canCreate(roomId)
private void subscribeToSession() {
final Subscription subscription = sessionInteractor.getDefault()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(allowed -> {
if (allowed) {
view.showRoom(hostname, roomId);
} else {
view.showHome();
.subscribe(session -> {
if (session == null || session.getToken() == null) {
view.showLoginScreen();
return;
}
String error = session.getError();
if (error != null && error.length() != 0) {
view.showConnectionError();
return;
}
if (!session.isTokenVerified()) {
view.showConnecting();
return;
}
view.showConnectionOk();
});
addSubscription(subscription);
......
......@@ -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() {
return sessionId;
}
......
......@@ -8,6 +8,7 @@ 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.Single;
import rx.android.schedulers.AndroidSchedulers;
public class RealmSessionRepository extends RealmRepository implements SessionRepository {
......@@ -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;
import chat.rocket.core.models.Session;
import chat.rocket.core.repositories.SessionRepository;
import rx.Observable;
import rx.Single;
public class SessionInteractor {
......@@ -23,6 +24,15 @@ public class SessionInteractor {
.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) {
if (session == null) {
return Session.State.UNAVAILABLE;
......
......@@ -19,6 +19,10 @@ public abstract class Session {
@Nullable
public abstract String getError();
public abstract Session withTokenVerified(boolean tokenVerified);
public abstract Session withError(String error);
public static Builder builder() {
return new AutoValue_Session.Builder();
}
......
......@@ -2,8 +2,11 @@ package chat.rocket.core.repositories;
import chat.rocket.core.models.Session;
import rx.Observable;
import rx.Single;
public interface SessionRepository {
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