Unverified Commit a886add5 authored by Rafael Kellermann Streit's avatar Rafael Kellermann Streit Committed by GitHub

Merge pull request #1128 from RocketChat/beta

[RELEASE] Merge beta into master
parents 7b7997d5 ac5c1dbc
Your Rocket.Chat.Android version: (make sure you are running the latest) ## Description
<!-- Version can be found by opening the side menu and then clicking on the chevron alongside username -->
<!-- Please, describe what's the issue here. -->
## Devices and Versions
<!-- Version can be found by opening the side menu and then clicking on "Settings" and then "About" -->
Your Rocket.Chat.Android version: (e.g. 2.1.0)
Your Rocket.Chat Server version: (e.g. 0.63.1-develop)
<!-- Found a bug? List all devices that reproduced it and all that doesn't --> <!-- Found a bug? List all devices that reproduced it and all that doesn't -->
Mobile device model and OS version: (e.g. "Nexus 7 - Android 6.0.1") Mobile device model and OS version: (e.g. "Nexus 7 - Android 6.0.1")
<!-- Don't forget to list the steps to reproduce. Stack traces may help too :) -->
## Steps to reproduce
<!-- In case it is a bug, can you describe the steps to reproduce it please? -->
## Logs
<!-- Do you have any logs? It can help the developers indentifying the cause in case it's a bug. -->
<!-- To get the logs, you can use [Logcat](https://developer.android.com/studio/debug/am-logcat.html) in Android Studio or you can use [Pidcat](https://github.com/JakeWharton/pidcat) -->
...@@ -13,8 +13,8 @@ android { ...@@ -13,8 +13,8 @@ android {
applicationId "chat.rocket.android" applicationId "chat.rocket.android"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion versions.targetSdk targetSdkVersion versions.targetSdk
versionCode 2011 versionCode 2012
versionName "2.0.1" versionName "2.0.2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
} }
......
...@@ -8,7 +8,6 @@ import chat.rocket.android.infrastructure.LocalRepository ...@@ -8,7 +8,6 @@ import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.* import chat.rocket.android.server.domain.*
import chat.rocket.android.server.domain.model.Account import chat.rocket.android.server.domain.model.Account
import chat.rocket.android.server.infraestructure.RocketChatClientFactory import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.server.presentation.CheckServerPresenter
import chat.rocket.android.util.extensions.* import chat.rocket.android.util.extensions.*
import chat.rocket.android.util.retryIO import chat.rocket.android.util.retryIO
import chat.rocket.common.RocketChatAuthException import chat.rocket.common.RocketChatAuthException
...@@ -31,24 +30,24 @@ private const val SERVICE_NAME_GITHUB = "github" ...@@ -31,24 +30,24 @@ private const val SERVICE_NAME_GITHUB = "github"
private const val SERVICE_NAME_GOOGLE = "google" private const val SERVICE_NAME_GOOGLE = "google"
private const val SERVICE_NAME_LINKEDIN = "linkedin" private const val SERVICE_NAME_LINKEDIN = "linkedin"
private const val SERVICE_NAME_GILAB = "gitlab" private const val SERVICE_NAME_GILAB = "gitlab"
private const val SERVICE_NAME_FACEBOOK = "facebook"
class LoginPresenter @Inject constructor(private val view: LoginView, class LoginPresenter @Inject constructor(
private val strategy: CancelStrategy, private val view: LoginView,
private val navigator: AuthenticationNavigator, private val strategy: CancelStrategy,
private val tokenRepository: TokenRepository, private val navigator: AuthenticationNavigator,
private val localRepository: LocalRepository, private val tokenRepository: TokenRepository,
private val getAccountsInteractor: GetAccountsInteractor, private val localRepository: LocalRepository,
private val settingsInteractor: GetSettingsInteractor, private val getAccountsInteractor: GetAccountsInteractor,
serverInteractor: GetCurrentServerInteractor, private val settingsInteractor: GetSettingsInteractor,
private val saveAccountInteractor: SaveAccountInteractor, serverInteractor: GetCurrentServerInteractor,
private val factory: RocketChatClientFactory) private val saveAccountInteractor: SaveAccountInteractor,
: CheckServerPresenter(strategy, factory, view) { private val factory: RocketChatClientFactory
) {
// TODO - we should validate the current server when opening the app, and have a nonnull get() // TODO - we should validate the current server when opening the app, and have a nonnull get()
private val currentServer = serverInteractor.get()!! private val currentServer = serverInteractor.get()!!
private lateinit var client: RocketChatClient private lateinit var client: RocketChatClient
private lateinit var settings: PublicSettings private lateinit var settings: PublicSettings
//private val client: RocketChatClient = factory.create(currentServer)
//private val settings: PublicSettings = settingsInteractor.get(currentServer)
private lateinit var usernameOrEmail: String private lateinit var usernameOrEmail: String
private lateinit var password: String private lateinit var password: String
private lateinit var credentialToken: String private lateinit var credentialToken: String
...@@ -62,7 +61,6 @@ class LoginPresenter @Inject constructor(private val view: LoginView, ...@@ -62,7 +61,6 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
setupUserRegistrationView() setupUserRegistrationView()
setupCasView() setupCasView()
setupOauthServicesView() setupOauthServicesView()
checkServerInfo(currentServer)
} }
fun authenticateWithUserAndPassword(usernameOrEmail: String, password: String) { fun authenticateWithUserAndPassword(usernameOrEmail: String, password: String) {
...@@ -92,25 +90,14 @@ class LoginPresenter @Inject constructor(private val view: LoginView, ...@@ -92,25 +90,14 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
doAuthentication(TYPE_LOGIN_OAUTH) doAuthentication(TYPE_LOGIN_OAUTH)
} }
fun authenticadeWithDeepLink(deepLinkInfo: LoginDeepLinkInfo) { fun authenticateWithDeepLink(deepLinkInfo: LoginDeepLinkInfo) {
val serverUrl = deepLinkInfo.url val serverUrl = deepLinkInfo.url
setupConnectionInfo(serverUrl) setupConnectionInfo(serverUrl)
deepLinkUserId = deepLinkInfo.userId deepLinkUserId = deepLinkInfo.userId
deepLinkToken = deepLinkInfo.token deepLinkToken = deepLinkInfo.token
tokenRepository.save(serverUrl, Token(deepLinkUserId, deepLinkToken)) tokenRepository.save(serverUrl, Token(deepLinkUserId, deepLinkToken))
launchUI(strategy) {
try { doAuthentication(TYPE_LOGIN_DEEP_LINK)
val version = checkServerVersion(serverUrl).await()
when (version) {
is Version.OutOfDateError -> {
view.blockAndAlertNotRequiredVersion()
}
else -> doAuthentication(TYPE_LOGIN_DEEP_LINK)
}
} catch (ex: Exception) {
Timber.d(ex, "Error performing deep link login")
}
}
} }
private fun setupConnectionInfo(serverUrl: String) { private fun setupConnectionInfo(serverUrl: String) {
...@@ -156,9 +143,12 @@ class LoginPresenter @Inject constructor(private val view: LoginView, ...@@ -156,9 +143,12 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
var totalSocialAccountsEnabled = 0 var totalSocialAccountsEnabled = 0
if (settings.isFacebookAuthenticationEnabled()) { if (settings.isFacebookAuthenticationEnabled()) {
// //TODO: Remove until we have this implemented val clientId = getOauthClientId(services, SERVICE_NAME_FACEBOOK)
// view.enableLoginByFacebook() if (clientId != null) {
// totalSocialAccountsEnabled++ view.setupFacebookButtonListener(OauthHelper.getFacebookOauthUrl(clientId, currentServer, state), state)
view.enableLoginByFacebook()
totalSocialAccountsEnabled++
}
} }
if (settings.isGithubAuthenticationEnabled()) { if (settings.isGithubAuthenticationEnabled()) {
val clientId = getOauthClientId(services, SERVICE_NAME_GITHUB) val clientId = getOauthClientId(services, SERVICE_NAME_GITHUB)
...@@ -291,7 +281,7 @@ class LoginPresenter @Inject constructor(private val view: LoginView, ...@@ -291,7 +281,7 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
private fun getOauthClientId(listMap: List<Map<String, String>>, serviceName: String): String? { private fun getOauthClientId(listMap: List<Map<String, String>>, serviceName: String): String? {
return listMap.find { map -> map.containsValue(serviceName) } return listMap.find { map -> map.containsValue(serviceName) }
?.get("appId") ?.get("appId")
} }
private suspend fun saveAccount(username: String) { private suspend fun saveAccount(username: String) {
......
...@@ -4,7 +4,7 @@ import chat.rocket.android.authentication.server.presentation.VersionCheckView ...@@ -4,7 +4,7 @@ import chat.rocket.android.authentication.server.presentation.VersionCheckView
import chat.rocket.android.core.behaviours.LoadingView import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView import chat.rocket.android.core.behaviours.MessageView
interface LoginView : LoadingView, MessageView, VersionCheckView { interface LoginView : LoadingView, MessageView {
/** /**
* Shows the form view (i.e the username/email and password fields) if it is enabled by the server settings. * Shows the form view (i.e the username/email and password fields) if it is enabled by the server settings.
...@@ -145,6 +145,14 @@ interface LoginView : LoadingView, MessageView, VersionCheckView { ...@@ -145,6 +145,14 @@ interface LoginView : LoadingView, MessageView, VersionCheckView {
*/ */
fun setupLinkedinButtonListener(linkedinUrl: String, state: String) fun setupLinkedinButtonListener(linkedinUrl: String, state: String)
/**
* Setups the Facebook button when tapped.
*
* @param facebookOauthUrl The Facebook OAuth URL to authenticate with.
* @param state A random string generated by the app, which you'll verify later (to protect against forgery attacks).
*/
fun setupFacebookButtonListener(facebookOauthUrl: String, state: String)
/** /**
* Shows the "login by Meteor" view if it is enable by the server settings. * Shows the "login by Meteor" view if it is enable by the server settings.
*/ */
......
...@@ -72,7 +72,7 @@ class LoginFragment : Fragment(), LoginView { ...@@ -72,7 +72,7 @@ class LoginFragment : Fragment(), LoginView {
} }
deepLinkInfo?.let { deepLinkInfo?.let {
presenter.authenticadeWithDeepLink(it) presenter.authenticateWithDeepLink(it)
}.ifNull { }.ifNull {
presenter.setupView() presenter.setupView()
} }
...@@ -261,6 +261,15 @@ class LoginFragment : Fragment(), LoginView { ...@@ -261,6 +261,15 @@ class LoginFragment : Fragment(), LoginView {
} }
} }
override fun setupFacebookButtonListener(facebookOauthUrl: String, state: String) {
ui { activity ->
button_facebook.setOnClickListener {
startActivityForResult(activity.oauthWebViewIntent(facebookOauthUrl, state), REQUEST_CODE_FOR_OAUTH)
activity.overridePendingTransition(R.anim.slide_up, R.anim.hold)
}
}
}
override fun enableLoginByGithub() { override fun enableLoginByGithub() {
ui { ui {
button_github.isClickable = true button_github.isClickable = true
...@@ -370,27 +379,6 @@ class LoginFragment : Fragment(), LoginView { ...@@ -370,27 +379,6 @@ class LoginFragment : Fragment(), LoginView {
} }
} }
override fun alertNotRecommendedVersion() {
ui {
AlertDialog.Builder(it)
.setMessage(getString(R.string.msg_ver_not_recommended, BuildConfig.RECOMMENDED_SERVER_VERSION))
.setPositiveButton(R.string.msg_ok, null)
.create()
.show()
}
}
override fun blockAndAlertNotRequiredVersion() {
ui {
AlertDialog.Builder(it)
.setMessage(getString(R.string.msg_ver_not_minimum, BuildConfig.REQUIRED_SERVER_VERSION))
.setOnDismissListener { activity?.onBackPressed() }
.setPositiveButton(R.string.msg_ok, null)
.create()
.show()
}
}
private fun showRemainingSocialAccountsView() { private fun showRemainingSocialAccountsView() {
social_accounts_container.postDelayed(300) { social_accounts_container.postDelayed(300) {
ui { ui {
......
...@@ -7,9 +7,10 @@ import chat.rocket.android.core.lifecycle.CancelStrategy ...@@ -7,9 +7,10 @@ import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.server.domain.GetAccountsInteractor import chat.rocket.android.server.domain.GetAccountsInteractor
import chat.rocket.android.server.domain.RefreshSettingsInteractor import chat.rocket.android.server.domain.RefreshSettingsInteractor
import chat.rocket.android.server.domain.SaveCurrentServerInteractor import chat.rocket.android.server.domain.SaveCurrentServerInteractor
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.server.presentation.CheckServerPresenter
import chat.rocket.android.util.extensions.isValidUrl import chat.rocket.android.util.extensions.isValidUrl
import chat.rocket.android.util.extensions.launchUI import chat.rocket.android.util.extensions.launchUI
import chat.rocket.common.util.ifNull
import javax.inject.Inject import javax.inject.Inject
class ServerPresenter @Inject constructor(private val view: ServerView, class ServerPresenter @Inject constructor(private val view: ServerView,
...@@ -17,7 +18,18 @@ class ServerPresenter @Inject constructor(private val view: ServerView, ...@@ -17,7 +18,18 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
private val navigator: AuthenticationNavigator, private val navigator: AuthenticationNavigator,
private val serverInteractor: SaveCurrentServerInteractor, private val serverInteractor: SaveCurrentServerInteractor,
private val refreshSettingsInteractor: RefreshSettingsInteractor, private val refreshSettingsInteractor: RefreshSettingsInteractor,
private val getAccountsInteractor: GetAccountsInteractor) { private val getAccountsInteractor: GetAccountsInteractor,
factory: RocketChatClientFactory
) : CheckServerPresenter(strategy, factory, view) {
fun checkServer(server: String) {
if (!server.isValidUrl()) {
view.showInvalidServerUrlMessage()
} else {
view.showLoading()
checkServerInfo(server)
}
}
fun connect(server: String) { fun connect(server: String) {
connectToServer(server) { connectToServer(server) {
...@@ -25,7 +37,7 @@ class ServerPresenter @Inject constructor(private val view: ServerView, ...@@ -25,7 +37,7 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
} }
} }
fun connectToServer(server: String, block: () -> Unit) { private fun connectToServer(server: String, block: () -> Unit) {
if (!server.isValidUrl()) { if (!server.isValidUrl()) {
view.showInvalidServerUrlMessage() view.showInvalidServerUrlMessage()
} else { } else {
......
...@@ -3,7 +3,7 @@ package chat.rocket.android.authentication.server.presentation ...@@ -3,7 +3,7 @@ package chat.rocket.android.authentication.server.presentation
import chat.rocket.android.core.behaviours.LoadingView import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView import chat.rocket.android.core.behaviours.MessageView
interface ServerView : LoadingView, MessageView { interface ServerView : LoadingView, MessageView, VersionCheckView {
/** /**
* Shows an invalid server URL message. * Shows an invalid server URL message.
......
...@@ -10,4 +10,9 @@ interface VersionCheckView { ...@@ -10,4 +10,9 @@ interface VersionCheckView {
* Block user to proceed and alert him due to server having an unsupported server version. * Block user to proceed and alert him due to server having an unsupported server version.
*/ */
fun blockAndAlertNotRequiredVersion() fun blockAndAlertNotRequiredVersion()
/**
* Do some action if version is ok. This is optional.
*/
fun versionOk() {}
} }
\ No newline at end of file
package chat.rocket.android.authentication.server.ui package chat.rocket.android.authentication.server.ui
import android.app.AlertDialog
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import chat.rocket.android.BuildConfig
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import chat.rocket.android.authentication.server.presentation.ServerPresenter import chat.rocket.android.authentication.server.presentation.ServerPresenter
import chat.rocket.android.authentication.server.presentation.ServerView import chat.rocket.android.authentication.server.presentation.ServerView
import chat.rocket.android.helper.KeyboardHelper import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.util.extensions.* import chat.rocket.android.util.extensions.*
import chat.rocket.common.util.ifNull
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_server.* import kotlinx.android.synthetic.main.fragment_authentication_server.*
import javax.inject.Inject import javax.inject.Inject
class ServerFragment : Fragment(), ServerView { class ServerFragment : Fragment(), ServerView {
@Inject lateinit var presenter: ServerPresenter @Inject
lateinit var presenter: ServerPresenter
private var deepLinkInfo: LoginDeepLinkInfo? = null private var deepLinkInfo: LoginDeepLinkInfo? = null
private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener { private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
text_server_url.isCursorVisible = KeyboardHelper.isSoftKeyboardShown(relative_layout.rootView) text_server_url.isCursorVisible = KeyboardHelper.isSoftKeyboardShown(relative_layout.rootView)
...@@ -49,6 +54,8 @@ class ServerFragment : Fragment(), ServerView { ...@@ -49,6 +54,8 @@ class ServerFragment : Fragment(), ServerView {
setupOnClickListener() setupOnClickListener()
deepLinkInfo?.let { deepLinkInfo?.let {
val uri = Uri.parse(it.url)
uri?.let { text_server_protocol.hintContent = it.host }
presenter.deepLink(it) presenter.deepLink(it)
} }
} }
...@@ -74,7 +81,7 @@ class ServerFragment : Fragment(), ServerView { ...@@ -74,7 +81,7 @@ class ServerFragment : Fragment(), ServerView {
} }
} }
override fun showMessage(resId: Int){ override fun showMessage(resId: Int) {
ui { ui {
showToast(resId) showToast(resId)
} }
...@@ -90,15 +97,60 @@ class ServerFragment : Fragment(), ServerView { ...@@ -90,15 +97,60 @@ class ServerFragment : Fragment(), ServerView {
showMessage(getString(R.string.msg_generic_error)) showMessage(getString(R.string.msg_generic_error))
} }
override fun alertNotRecommendedVersion() {
ui {
hideLoading()
AlertDialog.Builder(it)
.setMessage(getString(R.string.msg_ver_not_recommended, BuildConfig.RECOMMENDED_SERVER_VERSION))
.setPositiveButton(R.string.msg_ok, { _, _ ->
performConnect()
})
.create()
.show()
}
}
override fun blockAndAlertNotRequiredVersion() {
ui {
hideLoading()
AlertDialog.Builder(it)
.setMessage(getString(R.string.msg_ver_not_minimum, BuildConfig.REQUIRED_SERVER_VERSION))
.setPositiveButton(R.string.msg_ok, null)
.setOnDismissListener {
// reset the deeplink info, so the user can log to another server...
deepLinkInfo = null
}
.create()
.show()
}
}
override fun versionOk() {
performConnect()
}
private fun performConnect() {
ui {
deepLinkInfo?.let {
presenter.deepLink(it)
}.ifNull {
val url = text_server_url.textContent.ifEmpty(text_server_url.hintContent)
presenter.connect(text_server_protocol.textContent + url)
}
}
}
private fun enableUserInput(value: Boolean) { private fun enableUserInput(value: Boolean) {
button_connect.isEnabled = value button_connect.isEnabled = value
text_server_url.isEnabled = value text_server_url.isEnabled = value
} }
private fun setupOnClickListener() { private fun setupOnClickListener() {
button_connect.setOnClickListener { ui {
val url = text_server_url.textContent.ifEmpty(text_server_url.hintContent) button_connect.setOnClickListener {
presenter.connect(text_server_protocol.textContent + url) val url = text_server_url.textContent.ifEmpty(text_server_url.hintContent)
presenter.checkServer(text_server_protocol.textContent + url)
}
} }
} }
} }
\ No newline at end of file
...@@ -34,7 +34,7 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -34,7 +34,7 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
val deepLinkInfo = intent.getLoginDeepLinkInfo() val deepLinkInfo = intent.getLoginDeepLinkInfo()
launch(UI + job) { launch(UI + job) {
val newServer = intent.getBooleanExtra(INTENT_ADD_NEW_SERVER, false) val newServer = intent.getBooleanExtra(INTENT_ADD_NEW_SERVER, false)
// if we got authenticadeWithDeepLink information, pass true to newServer also // if we got authenticateWithDeepLink information, pass true to newServer also
presenter.loadCredentials(newServer || deepLinkInfo != null) { authenticated -> presenter.loadCredentials(newServer || deepLinkInfo != null) { authenticated ->
if (!authenticated) { if (!authenticated) {
showServerInput(savedInstanceState, deepLinkInfo) showServerInput(savedInstanceState, deepLinkInfo)
......
...@@ -15,9 +15,6 @@ import kotlinx.coroutines.experimental.Job ...@@ -15,9 +15,6 @@ import kotlinx.coroutines.experimental.Job
@PerFragment @PerFragment
class ChatRoomFragmentModule { class ChatRoomFragmentModule {
@Provides
fun provideChatRoomNavigator(activity: ChatRoomActivity) = ChatRoomNavigator(activity)
@Provides @Provides
fun chatRoomView(frag: ChatRoomFragment): ChatRoomView { fun chatRoomView(frag: ChatRoomFragment): ChatRoomView {
return frag return frag
......
package chat.rocket.android.chatroom.di
import chat.rocket.android.chatroom.presentation.ChatRoomNavigator
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.dagger.scope.PerActivity
import dagger.Module
import dagger.Provides
@Module
@PerActivity
class ChatRoomModule {
@Provides
fun provideChatRoomNavigator(activity: ChatRoomActivity) = ChatRoomNavigator(activity)
}
\ No newline at end of file
...@@ -3,6 +3,7 @@ package chat.rocket.android.chatroom.presentation ...@@ -3,6 +3,7 @@ package chat.rocket.android.chatroom.presentation
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.members.ui.newInstance import chat.rocket.android.members.ui.newInstance
import chat.rocket.android.server.ui.changeServerIntent
import chat.rocket.android.util.extensions.addFragmentBackStack import chat.rocket.android.util.extensions.addFragmentBackStack
class ChatRoomNavigator(internal val activity: ChatRoomActivity) { class ChatRoomNavigator(internal val activity: ChatRoomActivity) {
...@@ -12,4 +13,9 @@ class ChatRoomNavigator(internal val activity: ChatRoomActivity) { ...@@ -12,4 +13,9 @@ class ChatRoomNavigator(internal val activity: ChatRoomActivity) {
newInstance(chatRoomId, chatRoomType) newInstance(chatRoomId, chatRoomType)
} }
} }
fun toNewServer() {
activity.startActivity(activity.changeServerIntent())
activity.finish()
}
} }
\ No newline at end of file
...@@ -10,6 +10,7 @@ import chat.rocket.android.chatroom.viewmodel.ViewModelMapper ...@@ -10,6 +10,7 @@ import chat.rocket.android.chatroom.viewmodel.ViewModelMapper
import chat.rocket.android.chatroom.viewmodel.suggestion.ChatRoomSuggestionViewModel import chat.rocket.android.chatroom.viewmodel.suggestion.ChatRoomSuggestionViewModel
import chat.rocket.android.chatroom.viewmodel.suggestion.CommandSuggestionViewModel import chat.rocket.android.chatroom.viewmodel.suggestion.CommandSuggestionViewModel
import chat.rocket.android.chatroom.viewmodel.suggestion.PeopleSuggestionViewModel import chat.rocket.android.chatroom.viewmodel.suggestion.PeopleSuggestionViewModel
import chat.rocket.android.core.behaviours.showMessage
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.infrastructure.username import chat.rocket.android.infrastructure.username
...@@ -172,7 +173,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, ...@@ -172,7 +173,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
launchUI(strategy) { launchUI(strategy) {
view.showLoading() view.showLoading()
try { try {
val fileName = async { uriInteractor.getFileName(uri) }.await() val fileName = async { uriInteractor.getFileName(uri) }.await() ?: uri.toString()
val mimeType = async { uriInteractor.getMimeType(uri) }.await() val mimeType = async { uriInteractor.getMimeType(uri) }.await()
val fileSize = async { uriInteractor.getFileSize(uri) }.await() val fileSize = async { uriInteractor.getFileSize(uri) }.await()
val maxFileSize = settings.uploadMaxFileSize() val maxFileSize = settings.uploadMaxFileSize()
...@@ -189,12 +190,11 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, ...@@ -189,12 +190,11 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
} }
} }
} }
} catch (ex: RocketChatException) { } catch (ex: Exception) {
Timber.d(ex) Timber.d(ex, "Error uploading file")
ex.message?.let { when(ex) {
view.showMessage(it) is RocketChatException -> view.showMessage(ex)
}.ifNull { else -> view.showGenericErrorMessage()
view.showGenericErrorMessage()
} }
} finally { } finally {
view.hideLoading() view.hideLoading()
......
...@@ -8,12 +8,14 @@ import android.os.Bundle ...@@ -8,12 +8,14 @@ import android.os.Bundle
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.presentation.ChatRoomNavigator
import chat.rocket.android.server.domain.GetCurrentServerInteractor import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.util.extensions.addFragment import chat.rocket.android.util.extensions.addFragment
import chat.rocket.android.util.extensions.textContent import chat.rocket.android.util.extensions.textContent
import chat.rocket.common.model.RoomType import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf import chat.rocket.common.model.roomTypeOf
import chat.rocket.common.util.ifNull
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector import dagger.android.DispatchingAndroidInjector
...@@ -51,6 +53,7 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -51,6 +53,7 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
// TODO - workaround for now... We will move to a single activity // TODO - workaround for now... We will move to a single activity
@Inject lateinit var serverInteractor: GetCurrentServerInteractor @Inject lateinit var serverInteractor: GetCurrentServerInteractor
@Inject lateinit var navigator: ChatRoomNavigator
@Inject lateinit var managerFactory: ConnectionManagerFactory @Inject lateinit var managerFactory: ConnectionManagerFactory
private lateinit var chatRoomId: String private lateinit var chatRoomId: String
...@@ -66,7 +69,13 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -66,7 +69,13 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
setContentView(R.layout.activity_chat_room) setContentView(R.layout.activity_chat_room)
// Workaround for when we are coming to the app via the recents app and the app was killed. // Workaround for when we are coming to the app via the recents app and the app was killed.
managerFactory.create(serverInteractor.get()!!).connect() val serverUrl = serverInteractor.get()
if (serverUrl != null) {
managerFactory.create(serverUrl).connect()
} else {
navigator.toNewServer()
return
}
chatRoomId = intent.getStringExtra(INTENT_CHAT_ROOM_ID) chatRoomId = intent.getStringExtra(INTENT_CHAT_ROOM_ID)
requireNotNull(chatRoomId) { "no chat_room_id provided in Intent extras" } requireNotNull(chatRoomId) { "no chat_room_id provided in Intent extras" }
......
...@@ -8,6 +8,7 @@ import chat.rocket.android.authentication.signup.di.SignupFragmentProvider ...@@ -8,6 +8,7 @@ import chat.rocket.android.authentication.signup.di.SignupFragmentProvider
import chat.rocket.android.authentication.twofactor.di.TwoFAFragmentProvider import chat.rocket.android.authentication.twofactor.di.TwoFAFragmentProvider
import chat.rocket.android.authentication.ui.AuthenticationActivity import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.chatroom.di.ChatRoomFragmentProvider import chat.rocket.android.chatroom.di.ChatRoomFragmentProvider
import chat.rocket.android.chatroom.di.ChatRoomModule
import chat.rocket.android.chatroom.di.PinnedMessagesFragmentProvider import chat.rocket.android.chatroom.di.PinnedMessagesFragmentProvider
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.ui.PinnedMessagesActivity import chat.rocket.android.chatroom.ui.PinnedMessagesActivity
...@@ -45,7 +46,9 @@ abstract class ActivityBuilder { ...@@ -45,7 +46,9 @@ abstract class ActivityBuilder {
abstract fun bindMainActivity(): MainActivity abstract fun bindMainActivity(): MainActivity
@PerActivity @PerActivity
@ContributesAndroidInjector(modules = [ChatRoomFragmentProvider::class, MembersFragmentProvider::class]) @ContributesAndroidInjector(modules = [ChatRoomModule::class,
ChatRoomFragmentProvider::class,
MembersFragmentProvider::class])
abstract fun bindChatRoomActivity(): ChatRoomActivity abstract fun bindChatRoomActivity(): ChatRoomActivity
@PerActivity @PerActivity
......
...@@ -67,4 +67,21 @@ object OauthHelper { ...@@ -67,4 +67,21 @@ object OauthHelper {
"&response_type=code" + "&response_type=code" +
"&scope=read_user" "&scope=read_user"
} }
}
\ No newline at end of file /**
* Returns the Facebook Oauth URL.
*
* @param clientId The Facebook client ID.
* @param serverUrl The server URL.
* @param state An unguessable random string used to protect against forgery attacks.
* @return The Facebook Oauth URL.
*/
fun getFacebookOauthUrl(clientId: String, serverUrl: String, state: String): String {
return "https://facebook.com/v2.9/dialog/oauth" +
"?client_id=$clientId" +
"&redirect_uri=${serverUrl.removeTrailingSlash()}/_oauth/facebook?close" +
"&state=$state" +
"&response_type=code" +
"&scope=email"
}
}
...@@ -28,14 +28,21 @@ class ProfilePresenter @Inject constructor(private val view: ProfileView, ...@@ -28,14 +28,21 @@ class ProfilePresenter @Inject constructor(private val view: ProfileView,
view.showLoading() view.showLoading()
try { try {
val myself = retryIO("me") { client.me() } val myself = retryIO("me") { client.me() }
myselfId = myself.id!! val id = myself.id
val avatarUrl = serverUrl.avatarUrl(myself.username!!) val username = myself.username
view.showProfile( if (id == null || username == null) {
avatarUrl, view.showGenericErrorMessage()
myself.name ?: "", } else {
myself.username ?: "", myselfId = id
myself.emails?.get(0)?.address!! val avatarUrl = serverUrl.avatarUrl(username)
) val email = myself.emails?.getOrNull(0)?.address
view.showProfile(
avatarUrl,
myself.name ?: "",
myself.username ?: "",
email
)
}
} catch (exception: RocketChatException) { } catch (exception: RocketChatException) {
view.showMessage(exception) view.showMessage(exception)
} finally { } finally {
......
...@@ -2,7 +2,6 @@ package chat.rocket.android.profile.presentation ...@@ -2,7 +2,6 @@ package chat.rocket.android.profile.presentation
import chat.rocket.android.core.behaviours.LoadingView import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView import chat.rocket.android.core.behaviours.MessageView
import chat.rocket.core.model.Myself
interface ProfileView : LoadingView, MessageView { interface ProfileView : LoadingView, MessageView {
...@@ -14,7 +13,7 @@ interface ProfileView : LoadingView, MessageView { ...@@ -14,7 +13,7 @@ interface ProfileView : LoadingView, MessageView {
* @param username The user username. * @param username The user username.
* @param email The user email. * @param email The user email.
*/ */
fun showProfile(avatarUrl: String, name: String, username: String, email: String) fun showProfile(avatarUrl: String, name: String, username: String, email: String?)
/** /**
* Shows a profile update successfully message * Shows a profile update successfully message
......
...@@ -55,18 +55,18 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -55,18 +55,18 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
super.onDestroyView() super.onDestroyView()
} }
override fun showProfile(avatarUrl: String, name: String, username: String, email: String) { override fun showProfile(avatarUrl: String, name: String, username: String, email: String?) {
ui { ui {
image_avatar.setImageURI(avatarUrl) image_avatar.setImageURI(avatarUrl)
text_name.textContent = name text_name.textContent = name
text_username.textContent = username text_username.textContent = username
text_email.textContent = email text_email.textContent = email ?: ""
text_avatar_url.textContent = "" text_avatar_url.textContent = ""
currentName = name currentName = name
currentUsername = username currentUsername = username
currentEmail = email currentEmail = email ?: ""
currentAvatar = avatarUrl currentAvatar = avatarUrl
profile_container.setVisible(true) profile_container.setVisible(true)
......
...@@ -18,17 +18,18 @@ abstract class CheckServerPresenter constructor(private val strategy: CancelStra ...@@ -18,17 +18,18 @@ abstract class CheckServerPresenter constructor(private val strategy: CancelStra
private val factory: RocketChatClientFactory, private val factory: RocketChatClientFactory,
private val view: VersionCheckView) { private val view: VersionCheckView) {
private lateinit var currentServer: String private lateinit var currentServer: String
private val client: RocketChatClient by lazy { private lateinit var client: RocketChatClient
factory.create(currentServer)
}
internal fun checkServerInfo(serverUrl: String): Job { internal fun checkServerInfo(serverUrl: String): Job {
return launchUI(strategy) { return launchUI(strategy) {
try { try {
currentServer = serverUrl
client = factory.create(currentServer)
val version = checkServerVersion(serverUrl).await() val version = checkServerVersion(serverUrl).await()
when (version) { when (version) {
is Version.VersionOk -> { is Version.VersionOk -> {
Timber.i("Your version is nice! (Requires: 0.62.0, Yours: ${version.version})") Timber.i("Your version is nice! (Requires: 0.62.0, Yours: ${version.version})")
view.versionOk()
} }
is Version.RecommendedVersionWarning -> { is Version.RecommendedVersionWarning -> {
Timber.i("Your server ${version.version} is bellow recommended version ${BuildConfig.RECOMMENDED_SERVER_VERSION}") Timber.i("Your server ${version.version} is bellow recommended version ${BuildConfig.RECOMMENDED_SERVER_VERSION}")
......
...@@ -41,7 +41,7 @@ private const val INTENT_SERVER_URL = "INTENT_SERVER_URL" ...@@ -41,7 +41,7 @@ private const val INTENT_SERVER_URL = "INTENT_SERVER_URL"
private const val INTENT_CHAT_ROOM_NAME = "INTENT_CHAT_ROOM_NAME" private const val INTENT_CHAT_ROOM_NAME = "INTENT_CHAT_ROOM_NAME"
private const val INTENT_CHAT_ROOM_TYPE = "INTENT_CHAT_ROOM_TYPE" private const val INTENT_CHAT_ROOM_TYPE = "INTENT_CHAT_ROOM_TYPE"
fun Context.changeServerIntent(serverUrl: String?): Intent { fun Context.changeServerIntent(serverUrl: String? = null): Intent {
return Intent(this, ChangeServerActivity::class.java).apply { return Intent(this, ChangeServerActivity::class.java).apply {
serverUrl?.let { url -> serverUrl?.let { url ->
putExtra(INTENT_SERVER_URL, url) putExtra(INTENT_SERVER_URL, url)
......
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