Commit cf18e7f8 authored by Leonardo Aramaki's avatar Leonardo Aramaki

Implement go back action from LoginActivity to fix the user getting locked at this screen

parent b1514363
......@@ -2,10 +2,13 @@ package chat.rocket.android;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.hadisatrio.optional.Optional;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
......@@ -20,8 +23,6 @@ import chat.rocket.android.log.RCLog;
import chat.rocket.core.utils.Pair;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.annotations.NonNull;
import io.reactivex.annotations.Nullable;
import okhttp3.HttpUrl;
/**
......@@ -38,13 +39,12 @@ public class RocketChatCache {
private static final String KEY_SESSION_TOKEN = "KEY_SESSION_TOKEN";
private Context context;
private String session;
public RocketChatCache(Context context) {
this.context = context.getApplicationContext();
}
public void addOpenedRoom(@NonNull String roomId, long lastSeen) {
public void addOpenedRoom(@NotNull String roomId, long lastSeen) {
JSONObject openedRooms = getOpenedRooms();
try {
JSONObject room = new JSONObject().put("rid", roomId).put("ls", lastSeen);
......@@ -55,15 +55,15 @@ public class RocketChatCache {
setString(KEY_OPENED_ROOMS, openedRooms.toString());
}
public void removeOpenedRoom(@NonNull String roomId) {
public void removeOpenedRoom(@NotNull String roomId) {
JSONObject openedRooms = getOpenedRooms();
if (openedRooms.has(roomId)) {
openedRooms.remove(roomId);
}
}
public @NonNull
JSONObject getOpenedRooms() {
@NotNull
public JSONObject getOpenedRooms() {
String openedRooms = getString(KEY_OPENED_ROOMS, "");
if (openedRooms.isEmpty()) {
return new JSONObject();
......@@ -88,9 +88,9 @@ public class RocketChatCache {
setString(KEY_SELECTED_SERVER_HOSTNAME, newHostname);
}
public void addHostSiteName(@NonNull String currentHostname, @NonNull String siteName) {
public void addSiteName(@NotNull String currentHostname, @NotNull String siteName) {
try {
String hostSiteNamesJson = getHostSiteNamesJson();
String hostSiteNamesJson = getSiteName();
JSONObject jsonObject = (hostSiteNamesJson == null) ?
new JSONObject() : new JSONObject(hostSiteNamesJson);
jsonObject.put(currentHostname, siteName);
......@@ -100,8 +100,22 @@ public class RocketChatCache {
}
}
public @NonNull
String getHostSiteName(@NonNull String host) {
public void removeSiteName(@NotNull String hostname) {
try {
String siteNameJson = getSiteName();
JSONObject jsonObject = (siteNameJson == null) ?
new JSONObject() : new JSONObject(siteNameJson);
if (jsonObject.has(hostname)) {
jsonObject.remove(hostname);
}
setString(KEY_SELECTED_SITE_NAME, jsonObject.toString());
} catch (JSONException e) {
RCLog.e(e);
}
}
@NotNull
public String getHostSiteName(@NotNull String host) {
if (host.startsWith("http")) {
HttpUrl url = HttpUrl.parse(host);
if (url != null) {
......@@ -109,7 +123,7 @@ public class RocketChatCache {
}
}
try {
String hostSiteNamesJson = getHostSiteNamesJson();
String hostSiteNamesJson = getSiteName();
JSONObject jsonObject = (hostSiteNamesJson == null) ?
new JSONObject() : new JSONObject(hostSiteNamesJson);
host = getSiteUrlFor(host);
......@@ -120,18 +134,18 @@ public class RocketChatCache {
return "";
}
private @Nullable
String getHostSiteNamesJson() {
@Nullable
private String getSiteName() {
return getString(KEY_SELECTED_SITE_NAME, null);
}
public void addHostnameSiteUrl(@Nullable String hostnameAlias, @NonNull String currentHostname) {
public void addSiteUrl(@Nullable String hostnameAlias, @NotNull String currentHostname) {
String alias = null;
if (hostnameAlias != null) {
alias = hostnameAlias.toLowerCase();
}
try {
String selectedHostnameAliasJson = getLoginHostnamesJson();
String selectedHostnameAliasJson = getSiteUrlForAllServers();
JSONObject jsonObject = selectedHostnameAliasJson == null ?
new JSONObject() : new JSONObject(selectedHostnameAliasJson);
jsonObject.put(alias, currentHostname);
......@@ -141,14 +155,33 @@ public class RocketChatCache {
}
}
public @Nullable
String getSiteUrlFor(String hostname) {
private void removeSiteUrl(@NotNull String hostname) {
try {
String siteUrlForAllServersJson = getSiteUrlForAllServers();
JSONObject jsonObject = siteUrlForAllServersJson == null ?
new JSONObject() : new JSONObject(siteUrlForAllServersJson);
Iterator<String> keys = jsonObject.keys();
while (keys.hasNext()) {
String alias = keys.next();
if (hostname.equals(jsonObject.getString(alias))) {
jsonObject.remove(alias);
break;
}
}
setString(KEY_SELECTED_SITE_URL, jsonObject.toString());
} catch (JSONException e) {
RCLog.e(e);
}
}
@Nullable
public String getSiteUrlFor(String hostname) {
try {
String selectedServerHostname = getSelectedServerHostname();
if (getLoginHostnamesJson() == null || getLoginHostnamesJson().isEmpty()) {
if (getSiteUrlForAllServers() == null || getSiteUrlForAllServers().isEmpty()) {
return null;
}
return new JSONObject(getLoginHostnamesJson())
return new JSONObject(getSiteUrlForAllServers())
.optString(hostname, selectedServerHostname);
} catch (JSONException e) {
RCLog.e(e);
......@@ -156,12 +189,12 @@ public class RocketChatCache {
return null;
}
private @Nullable
String getLoginHostnamesJson() {
@Nullable
private String getSiteUrlForAllServers() {
return getString(KEY_SELECTED_SITE_URL, null);
}
public void addHostname(@NonNull String hostname, @Nullable String hostnameAvatarUri, String siteName) {
public void addHostname(@NotNull String hostname, @Nullable String hostnameAvatarUri, String siteName) {
String hostnameList = getString(KEY_HOSTNAME_LIST, null);
try {
JSONObject json;
......@@ -257,6 +290,7 @@ public class RocketChatCache {
}
}
@NonNull
private JSONObject getSelectedRoomIdJsonObject() throws JSONException {
String json = getString(KEY_SELECTED_ROOM_ID, null);
if (json == null) {
......@@ -367,4 +401,17 @@ public class RocketChatCache {
return null;
}
/**
* Wipe all given hostname entries and references from cache.
*/
public void clearSelectedHostnameReferences() {
String hostname = getSelectedServerHostname();
if (hostname != null) {
removeSiteName(hostname);
removeHostname(hostname);
removeSiteUrl(hostname);
setSelectedServerHostname(null);
}
}
}
......@@ -512,8 +512,8 @@ public class MethodCallHelper {
if (httpSiteUrl != null) {
String host = httpSiteUrl.host();
RocketChatCache rocketChatCache = new RocketChatCache(context);
rocketChatCache.addHostnameSiteUrl(host, currentHostname);
rocketChatCache.addHostSiteName(currentHostname, siteName);
rocketChatCache.addSiteUrl(host, currentHostname);
rocketChatCache.addSiteName(currentHostname, siteName);
}
}
......
......@@ -11,7 +11,7 @@ import chat.rocket.android.fragment.AbstractFragment;
import chat.rocket.android.widget.RoomToolbar;
import chat.rocket.core.models.User;
abstract class AbstractChatRoomFragment extends AbstractFragment {
public abstract class AbstractChatRoomFragment extends AbstractFragment {
private RoomToolbar roomToolbar;
@Nullable
......
......@@ -131,7 +131,7 @@ public class RoomFragment extends AbstractChatRoomFragment implements
private MethodCallHelper methodCallHelper;
private AbsoluteUrlHelper absoluteUrlHelper;
private Message edittingMessage = null;
private Message editingMessage = null;
private RoomToolbar toolbar;
......@@ -344,7 +344,7 @@ public class RoomFragment extends AbstractChatRoomFragment implements
optionalPane.ifPresent(pane -> pane.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
@Override
public void onPanelSlide(View view, float v) {
public void onPanelSlide(@NonNull View view, float v) {
messageFormManager.enableComposingText(false);
sidebarFragment.clearSearchViewFocus();
//Ref: ActionBarDrawerToggle#setProgress
......@@ -352,12 +352,12 @@ public class RoomFragment extends AbstractChatRoomFragment implements
}
@Override
public void onPanelOpened(View view) {
public void onPanelOpened(@NonNull View view) {
toolbar.setNavigationIconVerticalMirror(true);
}
@Override
public void onPanelClosed(View view) {
public void onPanelClosed(@NonNull View view) {
messageFormManager.enableComposingText(true);
toolbar.setNavigationIconVerticalMirror(false);
subPane.closePane();
......@@ -487,8 +487,8 @@ public class RoomFragment extends AbstractChatRoomFragment implements
@Override
public boolean onBackPressed() {
if (edittingMessage != null) {
edittingMessage = null;
if (editingMessage != null) {
editingMessage = null;
messageFormManager.clearComposingText();
}
return false;
......@@ -547,15 +547,15 @@ public class RoomFragment extends AbstractChatRoomFragment implements
}
private void sendMessage(String messageText) {
if (edittingMessage == null) {
if (editingMessage == null) {
presenter.sendMessage(messageText);
} else {
presenter.updateMessage(edittingMessage, messageText);
presenter.updateMessage(editingMessage, messageText);
}
}
@Override
public void setupWith(RocketChatAbsoluteUrl rocketChatAbsoluteUrl) {
public void setupWith(@NonNull RocketChatAbsoluteUrl rocketChatAbsoluteUrl) {
if (rocketChatAbsoluteUrl != null) {
token = rocketChatAbsoluteUrl.getToken();
userId = rocketChatAbsoluteUrl.getUserId();
......@@ -564,7 +564,7 @@ public class RoomFragment extends AbstractChatRoomFragment implements
}
@Override
public void render(Room room) {
public void render(@NonNull Room room) {
roomType = room.getType();
setToolbarTitle(room.getName());
......@@ -589,7 +589,7 @@ public class RoomFragment extends AbstractChatRoomFragment implements
}
@Override
public void showUserStatus(User user) {
public void showUserStatus(@NonNull User user) {
showToolbarUserStatuslIcon(user.getStatus());
}
......@@ -610,7 +610,7 @@ public class RoomFragment extends AbstractChatRoomFragment implements
public void onMessageSendSuccessfully() {
scrollToLatestMessage();
messageFormManager.onMessageSend();
edittingMessage = null;
editingMessage = null;
}
@Override
......@@ -629,15 +629,16 @@ public class RoomFragment extends AbstractChatRoomFragment implements
}
@Override
public void showMessages(List<Message> messages) {
public void showMessages(@NonNull List<? extends Message> messages) {
if (messageListAdapter == null) {
return;
}
messageListAdapter.updateData(messages);
messageListAdapter.updateData((List<Message>) messages);
}
@Override
public void showMessageSendFailure(Message message) {
public void showMessageSendFailure(@NonNull Message message) {
new AlertDialog.Builder(getContext())
.setPositiveButton(R.string.resend,
(dialog, which) -> presenter.resendMessage(message))
......@@ -648,7 +649,7 @@ public class RoomFragment extends AbstractChatRoomFragment implements
}
@Override
public void showMessageDeleteFailure(Message message) {
public void showMessageDeleteFailure(@NonNull Message message) {
new AlertDialog.Builder(getContext())
.setTitle(getContext().getString(R.string.failed_to_delete))
.setMessage(getContext().getString(R.string.failed_to_delete_message))
......@@ -667,12 +668,12 @@ public class RoomFragment extends AbstractChatRoomFragment implements
}
@Override
public void onReply(AbsoluteUrl absoluteUrl, String markdown, Message message) {
public void onReply(@NonNull AbsoluteUrl absoluteUrl, @NonNull String markdown, @NonNull Message message) {
messageFormManager.setReply(absoluteUrl, markdown, message);
}
@Override
public void onCopy(String message) {
public void onCopy(@NonNull String message) {
RocketChatApplication context = RocketChatApplication.getInstance();
ClipboardManager clipboardManager =
(ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
......@@ -680,7 +681,7 @@ public class RoomFragment extends AbstractChatRoomFragment implements
}
@Override
public void showMessageActions(Message message) {
public void showMessageActions(@NonNull Message message) {
Activity context = getActivity();
if (context != null && context instanceof MainActivity) {
MessagePopup.take(message)
......@@ -694,7 +695,7 @@ public class RoomFragment extends AbstractChatRoomFragment implements
}
private void onEditMessage(Message message) {
edittingMessage = message;
editingMessage = message;
messageFormManager.setEditMessage(message.getMessage());
}
......
package chat.rocket.android.fragment.chatroom
import android.support.v4.util.Pair
import com.hadisatrio.optional.Optional
import org.json.JSONException
import org.json.JSONObject
import chat.rocket.android.BackgroundLooper
import chat.rocket.android.RocketChatApplication
import chat.rocket.android.RocketChatCache
import chat.rocket.android.api.MethodCallHelper
import chat.rocket.android.helper.AbsoluteUrlHelper
import chat.rocket.android.helper.LogIfError
import chat.rocket.android.helper.Logger
import chat.rocket.android.log.RCLog
import chat.rocket.android.service.ConnectivityManagerApi
import chat.rocket.android.shared.BasePresenter
import chat.rocket.core.SyncState
import chat.rocket.core.interactors.MessageInteractor
import chat.rocket.core.models.Message
import chat.rocket.core.models.Room
import chat.rocket.core.models.Settings
import chat.rocket.core.models.User
import chat.rocket.core.repositories.RoomRepository
import chat.rocket.core.repositories.UserRepository
import io.reactivex.Flowable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
class RoomPresenter/* package */ internal constructor(private val roomId: String,
private val userRepository: UserRepository,
private val messageInteractor: MessageInteractor,
private val roomRepository: RoomRepository,
private val absoluteUrlHelper: AbsoluteUrlHelper,
private val methodCallHelper: MethodCallHelper,
private val connectivityManagerApi: ConnectivityManagerApi) : BasePresenter<RoomContract.View>(), RoomContract.Presenter {
private var currentRoom: Room? = null
private val roomUserPair: Single<Pair<Room, User>>
get() = Single.zip(
singleRoom,
currentUser,
BiFunction<Room, User, Pair<Room, User>> { first, second -> Pair(first, second) }
)
private val singleRoom: Single<Room>
get() = roomRepository.getById(roomId)
.filter(Predicate<Optional<Room>> { it.isPresent() })
.map<Room>(Function<Optional<Room>, Room> { it.get() })
.firstElement()
.toSingle()
private val currentUser: Single<User>
get() = userRepository.getCurrent()
.filter(Predicate<Optional<User>> { it.isPresent() })
.map<User>(Function<Optional<User>, User> { it.get() })
.firstElement()
.toSingle()
override fun bindView(view: RoomContract.View) {
super.bindView(view)
refreshRoom()
}
override fun refreshRoom() {
getRoomRoles()
getRoomInfo()
getRoomHistoryStateInfo()
getMessages()
getUserPreferences()
}
override fun loadMessages() {
val subscription = singleRoom
.flatMap<Boolean>(Function<Room, SingleSource<out Boolean>> { messageInteractor.loadMessages(it) })
package chat.rocket.android.fragment.chatroom;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.Pair;
import com.hadisatrio.optional.Optional;
import org.json.JSONException;
import org.json.JSONObject;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.RocketChatApplication;
import chat.rocket.android.RocketChatCache;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.helper.AbsoluteUrlHelper;
import chat.rocket.android.helper.LogIfError;
import chat.rocket.android.helper.Logger;
import chat.rocket.android.log.RCLog;
import chat.rocket.android.service.ConnectivityManagerApi;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.SyncState;
import chat.rocket.core.interactors.MessageInteractor;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.Settings;
import chat.rocket.core.models.User;
import chat.rocket.core.repositories.RoomRepository;
import chat.rocket.core.repositories.UserRepository;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
public class RoomPresenter extends BasePresenter<RoomContract.View>
implements RoomContract.Presenter {
private final String roomId;
private final MessageInteractor messageInteractor;
private final UserRepository userRepository;
private final RoomRepository roomRepository;
private final AbsoluteUrlHelper absoluteUrlHelper;
private final MethodCallHelper methodCallHelper;
private final ConnectivityManagerApi connectivityManagerApi;
private Room currentRoom;
/* package */RoomPresenter(String roomId,
UserRepository userRepository,
MessageInteractor messageInteractor,
RoomRepository roomRepository,
AbsoluteUrlHelper absoluteUrlHelper,
MethodCallHelper methodCallHelper,
ConnectivityManagerApi connectivityManagerApi) {
this.roomId = roomId;
this.userRepository = userRepository;
this.messageInteractor = messageInteractor;
this.roomRepository = roomRepository;
this.absoluteUrlHelper = absoluteUrlHelper;
this.methodCallHelper = methodCallHelper;
this.connectivityManagerApi = connectivityManagerApi;
}
@Override
public void bindView(@NonNull RoomContract.View view) {
super.bindView(view);
refreshRoom();
}
@Override
public void refreshRoom() {
getRoomRoles();
getRoomInfo();
getRoomHistoryStateInfo();
getMessages();
getUserPreferences();
}
@Override
public void loadMessages() {
final Disposable subscription = getSingleRoom()
.flatMap(messageInteractor::loadMessages)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ success ->
success -> {
if (!success) {
connectivityManagerApi.keepAliveServer()
connectivityManagerApi.keepAliveServer();
}
},
Consumer<Throwable> { Logger.report(it) }
)
Logger.INSTANCE::report
);
addSubscription(subscription)
addSubscription(subscription);
}
override fun loadMoreMessages() {
val subscription = singleRoom
.flatMap<Boolean>(Function<Room, SingleSource<out Boolean>> { messageInteractor.loadMoreMessages(it) })
@Override
public void loadMoreMessages() {
final Disposable subscription = getSingleRoom()
.flatMap(messageInteractor::loadMoreMessages)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ success ->
success -> {
if (!success) {
connectivityManagerApi.keepAliveServer()
connectivityManagerApi.keepAliveServer();
}
},
Consumer<Throwable> { Logger.report(it) }
)
Logger.INSTANCE::report
);
addSubscription(subscription)
addSubscription(subscription);
}
override fun onMessageSelected(message: Message?) {
@Override
public void onMessageSelected(@Nullable Message message) {
if (message == null) {
return
return;
}
if (message.syncState == SyncState.DELETE_FAILED) {
view.showMessageDeleteFailure(message)
} else if (message.syncState == SyncState.FAILED) {
view.showMessageSendFailure(message)
} else if (message.type == null && message.syncState == SyncState.SYNCED) {
if (message.getSyncState() == SyncState.DELETE_FAILED) {
view.showMessageDeleteFailure(message);
} else if (message.getSyncState() == SyncState.FAILED) {
view.showMessageSendFailure(message);
} else if (message.getType() == null && message.getSyncState() == SyncState.SYNCED) {
// If message is not a system message show applicable actions.
view.showMessageActions(message)
view.showMessageActions(message);
}
}
override fun onMessageTap(message: Message?) {
@Override
public void onMessageTap(@Nullable Message message) {
if (message == null) {
return
return;
}
if (message.syncState == SyncState.FAILED) {
view.showMessageSendFailure(message)
if (message.getSyncState() == SyncState.FAILED) {
view.showMessageSendFailure(message);
}
}
override fun replyMessage(message: Message, justQuote: Boolean) {
val subscription = this.absoluteUrlHelper.rocketChatAbsoluteUrl
@Override
public void replyMessage(@NonNull Message message, boolean justQuote) {
final Disposable subscription = this.absoluteUrlHelper.getRocketChatAbsoluteUrl()
.cache()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ serverUrl ->
if (serverUrl.isPresent) {
val absoluteUrl = serverUrl.get()
val baseUrl = absoluteUrl.baseUrl
view.onReply(absoluteUrl, buildReplyOrQuoteMarkdown(baseUrl, message, justQuote), message)
serverUrl -> {
if (serverUrl.isPresent()) {
RocketChatAbsoluteUrl absoluteUrl = serverUrl.get();
String baseUrl = absoluteUrl.getBaseUrl();
view.onReply(absoluteUrl, buildReplyOrQuoteMarkdown(baseUrl, message, justQuote), message);
}
},
Consumer<Throwable> { Logger.report(it) }
)
Logger.INSTANCE::report
);
addSubscription(subscription)
addSubscription(subscription);
}
override fun acceptMessageDeleteFailure(message: Message) {
val subscription = messageInteractor.acceptDeleteFailure(message)
public void acceptMessageDeleteFailure(Message message) {
final Disposable subscription = messageInteractor.acceptDeleteFailure(message)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe()
.subscribe();
addSubscription(subscription)
addSubscription(subscription);
}
override fun loadMissedMessages() {
val appContext = RocketChatApplication.getInstance()
val openedRooms = RocketChatCache(appContext).openedRooms
@Override
public void loadMissedMessages() {
RocketChatApplication appContext = RocketChatApplication.getInstance();
JSONObject openedRooms = new RocketChatCache(appContext).getOpenedRooms();
if (openedRooms.has(roomId)) {
try {
val room = openedRooms.getJSONObject(roomId)
val rid = room.optString("rid")
val ls = room.optLong("ls")
JSONObject room = openedRooms.getJSONObject(roomId);
String rid = room.optString("rid");
long ls = room.optLong("ls");
methodCallHelper.loadMissedMessages(rid, ls)
.continueWith(LogIfError())
} catch (e: JSONException) {
RCLog.e(e)
.continueWith(new LogIfError());
} catch (JSONException e) {
RCLog.e(e);
}
}
}
private fun buildReplyOrQuoteMarkdown(baseUrl: String, message: Message, justQuote: Boolean): String {
if (currentRoom == null || message.user == null) {
return ""
private String buildReplyOrQuoteMarkdown(String baseUrl, Message message, boolean justQuote) {
if (currentRoom == null || message.getUser() == null) {
return "";
}
return if (currentRoom!!.isDirectMessage) {
String.format("[ ](%s/direct/%s?msg=%s) ", baseUrl,
message.user!!.username,
message.id)
if (currentRoom.isDirectMessage()) {
return String.format("[ ](%s/direct/%s?msg=%s) ", baseUrl,
message.getUser().getUsername(),
message.getId());
} else {
String.format("[ ](%s/channel/%s?msg=%s) %s", baseUrl,
currentRoom!!.name,
message.id,
if (justQuote) "" else "@" + message.user!!.username + " ")
return String.format("[ ](%s/channel/%s?msg=%s) %s", baseUrl,
currentRoom.getName(),
message.getId(),
justQuote ? "" : "@" + message.getUser().getUsername() + " ");
}
}
override fun sendMessage(messageText: String) {
view.disableMessageInput()
val subscription = roomUserPair
.flatMap { pair -> messageInteractor.send(pair.first!!, pair.second!!, messageText) }
@Override
public void sendMessage(String messageText) {
view.disableMessageInput();
final Disposable subscription = getRoomUserPair()
.flatMap(pair -> messageInteractor.send(pair.first, pair.second, messageText))
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ success ->
success -> {
if (success) {
view.onMessageSendSuccessfully()
view.onMessageSendSuccessfully();
}
view.enableMessageInput()
}
) { throwable ->
view.enableMessageInput()
Logger.report(throwable)
view.enableMessageInput();
},
throwable -> {
view.enableMessageInput();
Logger.INSTANCE.report(throwable);
}
);
addSubscription(subscription)
addSubscription(subscription);
}
override fun resendMessage(message: Message) {
val subscription = currentUser
.flatMap { user -> messageInteractor.resend(message, user) }
@Override
public void resendMessage(@NonNull Message message) {
final Disposable subscription = getCurrentUser()
.flatMap(user -> messageInteractor.resend(message, user))
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe()
.subscribe();
addSubscription(subscription)
addSubscription(subscription);
}
override fun updateMessage(message: Message, content: String) {
view.disableMessageInput()
val subscription = currentUser
.flatMap { user -> messageInteractor.update(message, user, content) }
@Override
public void updateMessage(@NonNull Message message, String content) {
view.disableMessageInput();
final Disposable subscription = getCurrentUser()
.flatMap(user -> messageInteractor.update(message, user, content))
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ success ->
success -> {
if (success) {
view.onMessageSendSuccessfully()
}
view.enableMessageInput()
view.onMessageSendSuccessfully();
}
) { throwable ->
view.enableMessageInput()
Logger.report(throwable)
view.enableMessageInput();
},
throwable -> {
view.enableMessageInput();
Logger.INSTANCE.report(throwable);
}
);
addSubscription(subscription)
addSubscription(subscription);
}
override fun deleteMessage(message: Message) {
val subscription = messageInteractor.delete(message)
@Override
public void deleteMessage(@NonNull Message message) {
final Disposable subscription = messageInteractor.delete(message)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe()
.subscribe();
addSubscription(subscription)
addSubscription(subscription);
}
override fun onUnreadCount() {
val subscription = roomUserPair
.flatMap { roomUserPair ->
messageInteractor
.unreadCountFor(roomUserPair.first!!, roomUserPair.second!!)
}
@Override
public void onUnreadCount() {
final Disposable subscription = getRoomUserPair()
.flatMap(roomUserPair -> messageInteractor
.unreadCountFor(roomUserPair.first, roomUserPair.second))
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ count -> view.showUnreadCount(count) },
Consumer<Throwable> { Logger.report(it) }
)
count -> view.showUnreadCount(count),
Logger.INSTANCE::report
);
addSubscription(subscription)
addSubscription(subscription);
}
override fun onMarkAsRead() {
val subscription = roomRepository.getById(roomId)
.filter(Predicate<Optional<Room>> { it.isPresent() })
.map<Room>(Function<Optional<Room>, Room> { it.get() })
@Override
public void onMarkAsRead() {
final Disposable subscription = roomRepository.getById(roomId)
.filter(Optional::isPresent)
.map(Optional::get)
.firstElement()
.filter(Predicate<Room> { it.isAlert() })
.filter(Room::isAlert)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ room ->
methodCallHelper.readMessages(room.roomId)
.continueWith(LogIfError())
},
Consumer<Throwable> { Logger.report(it) }
)
room -> methodCallHelper.readMessages(room.getRoomId())
.continueWith(new LogIfError()),
Logger.INSTANCE::report
);
addSubscription(subscription)
addSubscription(subscription);
}
private fun getRoomRoles() {
methodCallHelper.getRoomRoles(roomId)
private void getRoomRoles() {
methodCallHelper.getRoomRoles(roomId);
}
private fun getRoomInfo() {
val subscription = roomRepository.getById(roomId)
private void getRoomInfo() {
final Disposable subscription = roomRepository.getById(roomId)
.distinctUntilChanged()
.filter(Predicate<Optional<Room>> { it.isPresent() })
.map<Room>(Function<Optional<Room>, Room> { it.get() })
.filter(Optional::isPresent)
.map(Optional::get)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Consumer<Room> { this.processRoom(it) }, Consumer<Throwable> { Logger.report(it) })
addSubscription(subscription)
.subscribe(this::processRoom, Logger.INSTANCE::report);
addSubscription(subscription);
}
private fun processRoom(room: Room) {
this.currentRoom = room
view.render(room)
private void processRoom(Room room) {
this.currentRoom = room;
view.render(room);
if (room.isDirectMessage) {
getUserByUsername(room.name)
if (room.isDirectMessage()) {
getUserByUsername(room.getName());
}
}
private fun getUserByUsername(username: String) {
val disposable = userRepository.getByUsername(username)
private void getUserByUsername(String username) {
final Disposable disposable = userRepository.getByUsername(username)
.distinctUntilChanged()
.filter(Predicate<Optional<User>> { it.isPresent() })
.map<User>(Function<Optional<User>, User> { it.get() })
.filter(Optional::isPresent)
.map(Optional::get)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Consumer<User> { view.showUserStatus(it) }, Consumer<Throwable> { Logger.report(it) })
addSubscription(disposable)
.subscribe(view::showUserStatus, Logger.INSTANCE::report);
addSubscription(disposable);
}
private fun getRoomHistoryStateInfo() {
val subscription = roomRepository.getHistoryStateByRoomId(roomId)
private void getRoomHistoryStateInfo() {
final Disposable subscription = roomRepository.getHistoryStateByRoomId(roomId)
.distinctUntilChanged()
.filter(Predicate<Optional<RoomHistoryState>> { it.isPresent() })
.map<RoomHistoryState>(Function<Optional<RoomHistoryState>, RoomHistoryState> { it.get() })
.filter(Optional::isPresent)
.map(Optional::get)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ roomHistoryState ->
val syncState = roomHistoryState.getSyncState()
roomHistoryState -> {
int syncState = roomHistoryState.getSyncState();
view.updateHistoryState(
!roomHistoryState.isComplete(),
syncState == SyncState.SYNCED || syncState == SyncState.FAILED
)
);
},
Consumer<Throwable> { Logger.report(it) }
)
Logger.INSTANCE::report
);
addSubscription(subscription)
addSubscription(subscription);
}
private fun getMessages() {
val subscription = Flowable.zip<Optional<Room>, Optional<RocketChatAbsoluteUrl>, Pair<Optional<Room>, Optional<RocketChatAbsoluteUrl>>>(roomRepository.getById(roomId),
absoluteUrlHelper.rocketChatAbsoluteUrl.toFlowable().cache(), BiFunction<Optional<Room>, Optional<RocketChatAbsoluteUrl>, Pair<Optional<Room>, Optional<RocketChatAbsoluteUrl>>> { first, second -> Pair(first, second) })
private void getMessages() {
final Disposable subscription = Flowable.zip(roomRepository.getById(roomId),
absoluteUrlHelper.getRocketChatAbsoluteUrl().toFlowable().cache(), Pair::new)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.map<Optional<Room>> { pair ->
view.setupWith(pair.second!!.orNull())
pair.first
}
.filter(Predicate<Optional<Room>> { it.isPresent() })
.map<Room>(Function<Optional<Room>, Room> { it.get() })
.map { room ->
RocketChatCache(RocketChatApplication.getInstance())
.addOpenedRoom(room.roomId, room.lastSeen)
room
}
.flatMap<List<Message>>(Function<Room, Publisher<out List<Message>>> { messageInteractor.getAllFrom(it) })
.map(pair -> {
view.setupWith(pair.second.orNull());
return pair.first;
})
.filter(Optional::isPresent)
.map(Optional::get)
.map(room -> {
new RocketChatCache(RocketChatApplication.getInstance())
.addOpenedRoom(room.getRoomId(), room.getLastSeen());
return room;
})
.flatMap(messageInteractor::getAllFrom)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
Consumer<List<Message>> { view.showMessages(it) },
Consumer<Throwable> { Logger.report(it) }
)
view::showMessages,
Logger.INSTANCE::report
);
addSubscription(subscription)
addSubscription(subscription);
}
private fun getUserPreferences() {
val subscription = userRepository.getCurrent()
.filter(Predicate<Optional<User>> { it.isPresent() })
.map<User>(Function<Optional<User>, User> { it.get() })
.filter { user -> user.settings != null }
.map<Settings>(Function<User, Settings> { it.getSettings() })
.filter { settings -> settings.preferences != null }
.map<Preferences>(Function<Settings, Preferences> { it.getPreferences() })
private void getUserPreferences() {
final Disposable subscription = userRepository.getCurrent()
.filter(Optional::isPresent)
.map(Optional::get)
.filter(user -> user.getSettings() != null)
.map(User::getSettings)
.filter(settings -> settings.getPreferences() != null)
.map(Settings::getPreferences)
.distinctUntilChanged()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ preferences ->
preferences -> {
if (preferences.isAutoImageLoad()) {
view.autoloadImages()
view.autoloadImages();
} else {
view.manualLoadImages()
view.manualLoadImages();
}
},
Consumer<Throwable> { Logger.report(it) }
)
Logger.INSTANCE::report
);
addSubscription(subscription)
addSubscription(subscription);
}
private fun getAbsoluteUrl() {
val subscription = absoluteUrlHelper.rocketChatAbsoluteUrl
private void getAbsoluteUrl() {
final Disposable subscription = absoluteUrlHelper.getRocketChatAbsoluteUrl()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ it -> view.setupWith(it.orNull()) },
Consumer<Throwable> { Logger.report(it) }
)
it -> view.setupWith(it.orNull()),
Logger.INSTANCE::report
);
addSubscription(subscription)
addSubscription(subscription);
}
private Single<Pair<Room, User>> getRoomUserPair() {
return Single.zip(
getSingleRoom(),
getCurrentUser(),
Pair::new
);
}
private Single<Room> getSingleRoom() {
return roomRepository.getById(roomId)
.filter(Optional::isPresent)
.map(Optional::get)
.firstElement()
.toSingle();
}
private Single<User> getCurrentUser() {
return userRepository.getCurrent()
.filter(Optional::isPresent)
.map(Optional::get)
.firstElement()
.toSingle();
}
}
......@@ -8,7 +8,7 @@ import chat.rocket.android.R;
import chat.rocket.android.fragment.AbstractFragment;
import chat.rocket.android.helper.TextUtils;
abstract class AbstractServerConfigFragment extends AbstractFragment {
public abstract class AbstractServerConfigFragment extends AbstractFragment {
public static final String KEY_HOSTNAME = "hostname";
protected String hostname;
......
......@@ -99,14 +99,14 @@ class LoginFragment : AbstractServerConfigFragment(), LoginContract.View {
showFragmentWithBackStack(fragment)
}
}
viewMap[info.serviceName]?.setVisibility(View.VISIBLE)
viewMap[info.serviceName]?.visibility = View.VISIBLE
}
}
}
for (info in OAuthProviderInfo.LIST) {
if (supportedMap[info.serviceName] == false) {
viewMap[info.serviceName]?.setVisibility(View.GONE)
viewMap[info.serviceName]?.visibility = View.GONE
}
}
}
......
......@@ -3,10 +3,14 @@ package chat.rocket.android.fragment.server_config
import bolts.Continuation
import bolts.Task
import chat.rocket.android.BackgroundLooper
import chat.rocket.android.LaunchUtil
import chat.rocket.android.RocketChatApplication
import chat.rocket.android.RocketChatCache
import chat.rocket.android.api.MethodCallHelper
import chat.rocket.android.api.TwoStepAuthException
import chat.rocket.android.helper.Logger
import chat.rocket.android.helper.TextUtils
import chat.rocket.android.service.ConnectivityManager
import chat.rocket.android.shared.BasePresenter
import chat.rocket.core.PublicSettingsConstants
import chat.rocket.core.models.PublicSetting
......@@ -26,6 +30,20 @@ class LoginPresenter(private val loginServiceConfigurationRepository: LoginServi
getLoginServices()
}
override fun release() {
val context = RocketChatApplication.getInstance()
val rocketChatCache = RocketChatCache(context)
val hostname = rocketChatCache.selectedServerHostname
hostname?.let {
ConnectivityManager.getInstance(context).removeServer(hostname)
rocketChatCache.clearSelectedHostnameReferences()
}
super.release()
LaunchUtil.showMainActivity(context)
}
override fun login(username: String, password: String) {
if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
return
......@@ -50,7 +68,9 @@ class LoginPresenter(private val loginServiceConfigurationRepository: LoginServi
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy(
onNext = { loginServiceConfigurations -> view.showLoginServices(loginServiceConfigurations) },
onNext = { loginServiceConfigurations ->
view.showLoginServices(loginServiceConfigurations);
},
onError = { Logger.report(it) }
)
)
......
package chat.rocket.android.helper
import chat.rocket.android.BuildConfig
import com.crashlytics.android.Crashlytics
import com.google.firebase.crash.FirebaseCrash
import chat.rocket.android.BuildConfig
object Logger {
fun report(throwable: Throwable) {
......
......@@ -22,7 +22,6 @@ import chat.rocket.android.BuildConfig
import chat.rocket.android.R
import chat.rocket.android.RocketChatCache
import chat.rocket.android.activity.MainActivity
import chat.rocket.android.extensions.printStackTraceOnDebug
import chat.rocket.android.helper.Logger
import chat.rocket.core.interactors.MessageInteractor
import chat.rocket.core.models.Room
......
......@@ -107,7 +107,7 @@ import io.reactivex.subjects.BehaviorSubject;
public void removeServer(String hostname) {
RealmBasedServerInfo.remove(hostname);
if (serverConnectivityList.containsKey(hostname)) {
disconnectFromServerIfNeeded(hostname)
disconnectFromServerIfNeeded(hostname, DDPClient.REASON_CLOSED_BY_USER)
.subscribe(_val -> {
}, RCLog::e);
}
......@@ -207,7 +207,7 @@ import io.reactivex.subjects.BehaviorSubject;
});
}
private Single<Boolean> disconnectFromServerIfNeeded(String hostname) {
private Single<Boolean> disconnectFromServerIfNeeded(String hostname, int reason) {
return Single.defer(() -> {
final int connectivity = serverConnectivityList.get(hostname);
if (connectivity == ServerConnectivity.STATE_DISCONNECTED) {
......@@ -216,8 +216,8 @@ import io.reactivex.subjects.BehaviorSubject;
if (connectivity == ServerConnectivity.STATE_CONNECTING) {
return waitForConnected(hostname)
.doOnError(err -> notifyConnectionLost(hostname, DDPClient.REASON_NETWORK_ERROR))
.flatMap(_val -> disconnectFromServerIfNeeded(hostname));
// .doOnError(err -> notifyConnectionLost(hostname, DDPClient.REASON_CLOSED_BY_USER))
.flatMap(_val -> disconnectFromServerIfNeeded(hostname, DDPClient.REASON_CLOSED_BY_USER));
}
if (connectivity == ServerConnectivity.STATE_DISCONNECTING) {
......
......@@ -11,84 +11,84 @@
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.constraint.ConstraintLayout
android:id="@+id/container"
android:layout_width="wrap_content"
android:minWidth="280dp"
android:layout_height="wrap_content"
android:paddingStart="@dimen/margin_16"
android:paddingLeft="@dimen/margin_16"
android:background="@drawable/container_bg"
android:minWidth="280dp"
android:paddingBottom="@dimen/margin_8"
android:paddingEnd="@dimen/margin_16"
android:paddingLeft="@dimen/margin_16"
android:paddingRight="@dimen/margin_16"
android:paddingStart="@dimen/margin_16"
android:paddingTop="@dimen/margin_8"
android:paddingBottom="@dimen/margin_8"
android:background="@drawable/container_bg"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
app:layout_constraintTop_toTopOf="parent">
<ImageButton
android:id="@+id/btn_login_with_twitter"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="fitXY"
app:srcCompat="@drawable/ic_button_twitter_24dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/text_input_username"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/btn_login_with_facebook"
android:background="?attr/selectableItemBackgroundBorderless" />
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_button_twitter_24dp" />
<ImageButton
android:id="@+id/btn_login_with_facebook"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="fitXY"
app:srcCompat="@drawable/ic_button_facebook_24dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/text_input_username"
app:layout_constraintLeft_toRightOf="@+id/btn_login_with_twitter"
app:layout_constraintRight_toLeftOf="@+id/btn_login_with_github"
android:background="?attr/selectableItemBackgroundBorderless" />
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_button_facebook_24dp" />
<ImageButton
android:id="@+id/btn_login_with_github"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="fitXY"
app:srcCompat="@drawable/ic_button_github_24dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/text_input_username"
app:layout_constraintLeft_toRightOf="@+id/btn_login_with_facebook"
app:layout_constraintRight_toLeftOf="@+id/btn_login_with_google"
android:background="?attr/selectableItemBackgroundBorderless" />
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_button_github_24dp" />
<ImageButton
android:id="@+id/btn_login_with_google"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="fitXY"
app:srcCompat="@drawable/ic_button_google_24dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/text_input_username"
app:layout_constraintLeft_toRightOf="@+id/btn_login_with_github"
app:layout_constraintRight_toRightOf="parent"
android:background="?attr/selectableItemBackgroundBorderless" />
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_button_google_24dp" />
<android.support.design.widget.TextInputLayout
android:id="@+id/text_input_username"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/btn_login_with_twitter"
app:layout_constraintBottom_toTopOf="@+id/text_input_passwd"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_login_with_twitter">
<android.support.design.widget.TextInputEditText
android:id="@+id/editor_username"
......@@ -104,10 +104,10 @@
android:id="@+id/text_input_passwd"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/text_input_username"
app:layout_constraintBottom_toTopOf="@+id/btn_user_registration"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_input_username">
<android.support.design.widget.TextInputEditText
android:id="@+id/editor_passwd"
......@@ -121,27 +121,27 @@
<Button
android:id="@+id/btn_user_registration"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_8"
android:text="@string/fragment_login_sign_up"
app:layout_constraintTop_toBottomOf="@+id/text_input_passwd"
app:layout_constraintRight_toLeftOf="@+id/btn_login_with_email"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
style="@style/Widget.AppCompat.Button.Colored" />
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/btn_login_with_email"
app:layout_constraintTop_toBottomOf="@+id/text_input_passwd" />
<Button
android:id="@+id/btn_login_with_email"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_8"
android:text="@string/fragment_login_sign_in"
app:layout_constraintTop_toBottomOf="@+id/text_input_passwd"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="@+id/btn_user_registration"
app:layout_constraintBottom_toBottomOf="parent"
style="@style/Widget.AppCompat.Button.Colored" />
app:layout_constraintLeft_toRightOf="@+id/btn_user_registration"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_input_passwd" />
</android.support.constraint.ConstraintLayout>
</ScrollView>
......
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