Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
AloqaIM-Android
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
AloqaIM-Android
Commits
95a28de4
Unverified
Commit
95a28de4
authored
Apr 17, 2018
by
divyanshu bhargava
Committed by
GitHub
Apr 17, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7 from RocketChat/develop-2.x
merge
parents
513931f0
eb73cd48
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
442 additions
and
90 deletions
+442
-90
build.gradle
app/build.gradle
+6
-2
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+15
-1
LoginDeepLinkInfo.kt
.../android/authentication/domain/model/LoginDeepLinkInfo.kt
+38
-0
LoginPresenter.kt
...droid/authentication/login/presentation/LoginPresenter.kt
+48
-6
LoginFragment.kt
...t/rocket/android/authentication/login/ui/LoginFragment.kt
+16
-2
AuthenticationNavigator.kt
...id/authentication/presentation/AuthenticationNavigator.kt
+7
-0
ServerPresenter.kt
...oid/authentication/server/presentation/ServerPresenter.kt
+16
-6
ServerFragment.kt
...rocket/android/authentication/server/ui/ServerFragment.kt
+15
-1
TwoFAFragment.kt
...cket/android/authentication/twofactor/ui/TwoFAFragment.kt
+1
-1
AuthenticationActivity.kt
...ocket/android/authentication/ui/AuthenticationActivity.kt
+8
-5
ChatRoomAdapter.kt
...a/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
+5
-0
ColorAttachmentViewHolder.kt
...ket/android/chatroom/adapter/ColorAttachmentViewHolder.kt
+38
-0
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+2
-2
BaseViewModel.kt
...a/chat/rocket/android/chatroom/viewmodel/BaseViewModel.kt
+2
-1
ColorAttachmentViewModel.kt
...et/android/chatroom/viewmodel/ColorAttachmentViewModel.kt
+24
-0
ViewModelMapper.kt
...chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
+14
-0
MessageView.kt
...n/java/chat/rocket/android/core/behaviours/MessageView.kt
+9
-0
AppModule.kt
.../main/java/chat/rocket/android/dagger/module/AppModule.kt
+14
-6
ForMessages.kt
.../java/chat/rocket/android/dagger/qualifier/ForMessages.kt
+11
-0
MainPresenter.kt
...va/chat/rocket/android/main/presentation/MainPresenter.kt
+2
-2
RefreshSettingsInteractor.kt
...rocket/android/server/domain/RefreshSettingsInteractor.kt
+4
-1
CheckServerPresenter.kt
...ocket/android/server/presentation/CheckServerPresenter.kt
+47
-14
fragment_profile.xml
app/src/main/res/layout/fragment_profile.xml
+48
-40
item_color_attachment.xml
app/src/main/res/layout/item_color_attachment.xml
+44
-0
backup_config.xml
app/src/main/res/xml/backup_config.xml
+8
-0
No files found.
app/build.gradle
View file @
95a28de4
...
@@ -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
20
09
versionCode
20
10
versionName
"2.0.0
-rc1
"
versionName
"2.0.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled
true
multiDexEnabled
true
}
}
...
@@ -124,6 +124,10 @@ kotlin {
...
@@ -124,6 +124,10 @@ kotlin {
}
}
}
}
androidExtensions
{
experimental
=
true
}
// FIXME - build and install the sdk into the app/libs directory
// FIXME - build and install the sdk into the app/libs directory
// We were having some issues with the kapt generated files from the sdk when importing as a module
// We were having some issues with the kapt generated files from the sdk when importing as a module
task
compileSdk
(
type:
Exec
)
{
task
compileSdk
(
type:
Exec
)
{
...
...
app/src/main/AndroidManifest.xml
View file @
95a28de4
...
@@ -17,10 +17,11 @@
...
@@ -17,10 +17,11 @@
<application
<application
android:name=
".app.RocketChatApplication"
android:name=
".app.RocketChatApplication"
android:allowBackup=
"true"
android:allowBackup=
"true"
android:fullBackupContent=
"@xml/backup_config"
android:icon=
"@mipmap/ic_launcher"
android:icon=
"@mipmap/ic_launcher"
android:label=
"@string/app_name"
android:label=
"@string/app_name"
android:roundIcon=
"@mipmap/ic_launcher_round"
android:roundIcon=
"@mipmap/ic_launcher_round"
android:networkSecurityConfig=
"@xml/network_security_config"
>
android:networkSecurityConfig=
"@xml/network_security_config"
android:supportsRtl=
"true"
>
android:supportsRtl=
"true"
>
<activity
<activity
...
@@ -34,6 +35,19 @@
...
@@ -34,6 +35,19 @@
<category
android:name=
"android.intent.category.DEFAULT"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
<intent-filter>
<action
android:name=
"android.intent.action.VIEW"
/>
<category
android:name=
"android.intent.category.BROWSABLE"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
<data
android:host=
"auth"
android:scheme=
"rocketchat"
/>
<data
android:host=
"go.rocket.chat"
android:path=
"/auth"
android:scheme=
"https"
/>
</intent-filter>
</intent-filter>
</activity>
</activity>
<activity
<activity
...
...
app/src/main/java/chat/rocket/android/authentication/domain/model/LoginDeepLinkInfo.kt
0 → 100644
View file @
95a28de4
package
chat.rocket.android.authentication.domain.model
import
android.content.Intent
import
android.net.Uri
import
android.os.Parcelable
import
kotlinx.android.parcel.Parcelize
import
timber.log.Timber
@Parcelize
data class
LoginDeepLinkInfo
(
val
url
:
String
,
val
userId
:
String
,
val
token
:
String
)
:
Parcelable
fun
Intent
.
getLoginDeepLinkInfo
():
LoginDeepLinkInfo
?
{
val
uri
=
data
return
if
(
action
==
Intent
.
ACTION_VIEW
&&
uri
!=
null
&&
uri
.
isAuthenticationDeepLink
())
{
val
host
=
uri
.
getQueryParameter
(
"host"
)
val
url
=
if
(
host
.
startsWith
(
"http"
))
host
else
"https://$host"
val
userId
=
uri
.
getQueryParameter
(
"userId"
)
val
token
=
uri
.
getQueryParameter
(
"token"
)
try
{
LoginDeepLinkInfo
(
url
,
userId
,
token
)
}
catch
(
ex
:
Exception
)
{
Timber
.
d
(
ex
,
"Error parsing login deeplink"
)
null
}
}
else
null
}
private
inline
fun
Uri
.
isAuthenticationDeepLink
():
Boolean
{
if
(
host
==
"auth"
)
return
true
else
if
(
host
==
"go.rocket.chat"
&&
path
==
"/auth"
)
return
true
return
false
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/login/presentation/LoginPresenter.kt
View file @
95a28de4
package
chat.rocket.android.authentication.login.presentation
package
chat.rocket.android.authentication.login.presentation
import
chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.OauthHelper
import
chat.rocket.android.helper.OauthHelper
...
@@ -10,6 +11,7 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory
...
@@ -10,6 +11,7 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.presentation.CheckServerPresenter
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.RocketChatException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatTwoFactorException
import
chat.rocket.common.RocketChatTwoFactorException
import
chat.rocket.common.model.Token
import
chat.rocket.common.model.Token
...
@@ -24,6 +26,7 @@ import javax.inject.Inject
...
@@ -24,6 +26,7 @@ import javax.inject.Inject
private
const
val
TYPE_LOGIN_USER_EMAIL
=
0
private
const
val
TYPE_LOGIN_USER_EMAIL
=
0
private
const
val
TYPE_LOGIN_CAS
=
1
private
const
val
TYPE_LOGIN_CAS
=
1
private
const
val
TYPE_LOGIN_OAUTH
=
2
private
const
val
TYPE_LOGIN_OAUTH
=
2
private
const
val
TYPE_LOGIN_DEEP_LINK
=
3
private
const
val
SERVICE_NAME_GITHUB
=
"github"
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"
...
@@ -35,26 +38,31 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
...
@@ -35,26 +38,31 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
private
val
tokenRepository
:
TokenRepository
,
private
val
tokenRepository
:
TokenRepository
,
private
val
localRepository
:
LocalRepository
,
private
val
localRepository
:
LocalRepository
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
,
settingsInteractor
:
GetSettingsInteractor
,
private
val
settingsInteractor
:
GetSettingsInteractor
,
serverInteractor
:
GetCurrentServerInteractor
,
serverInteractor
:
GetCurrentServerInteractor
,
private
val
saveAccountInteractor
:
SaveAccountInteractor
,
private
val
saveAccountInteractor
:
SaveAccountInteractor
,
private
val
factory
:
RocketChatClientFactory
)
private
val
factory
:
RocketChatClientFactory
)
:
CheckServerPresenter
(
strategy
,
factory
.
create
(
serverInteractor
.
get
()
!!
)
,
view
)
{
:
CheckServerPresenter
(
strategy
,
factory
,
view
)
{
// 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
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
private
lateinit
var
client
:
RocketChatClient
private
val
settings
:
PublicSettings
=
settingsInteractor
.
get
(
currentServer
)
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
private
lateinit
var
credentialSecret
:
String
private
lateinit
var
credentialSecret
:
String
private
lateinit
var
deepLinkUserId
:
String
private
lateinit
var
deepLinkToken
:
String
fun
setupView
()
{
fun
setupView
()
{
setupConnectionInfo
(
currentServer
)
setupLoginView
()
setupLoginView
()
setupUserRegistrationView
()
setupUserRegistrationView
()
setupCasView
()
setupCasView
()
setupOauthServicesView
()
setupOauthServicesView
()
checkServerInfo
()
checkServerInfo
(
currentServer
)
}
}
fun
authenticateWithUserAndPassword
(
usernameOrEmail
:
String
,
password
:
String
)
{
fun
authenticateWithUserAndPassword
(
usernameOrEmail
:
String
,
password
:
String
)
{
...
@@ -84,6 +92,32 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
...
@@ -84,6 +92,32 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
doAuthentication
(
TYPE_LOGIN_OAUTH
)
doAuthentication
(
TYPE_LOGIN_OAUTH
)
}
}
fun
authenticadeWithDeepLink
(
deepLinkInfo
:
LoginDeepLinkInfo
)
{
val
serverUrl
=
deepLinkInfo
.
url
setupConnectionInfo
(
serverUrl
)
deepLinkUserId
=
deepLinkInfo
.
userId
deepLinkToken
=
deepLinkInfo
.
token
tokenRepository
.
save
(
serverUrl
,
Token
(
deepLinkUserId
,
deepLinkToken
))
launchUI
(
strategy
)
{
try
{
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
)
{
client
=
factory
.
create
(
serverUrl
)
settings
=
settingsInteractor
.
get
(
serverUrl
)
}
fun
signup
()
=
navigator
.
toSignUp
()
fun
signup
()
=
navigator
.
toSignUp
()
private
fun
setupLoginView
()
{
private
fun
setupLoginView
()
{
...
@@ -212,8 +246,16 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
...
@@ -212,8 +246,16 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
TYPE_LOGIN_OAUTH
->
{
TYPE_LOGIN_OAUTH
->
{
client
.
loginWithOauth
(
credentialToken
,
credentialSecret
)
client
.
loginWithOauth
(
credentialToken
,
credentialSecret
)
}
}
TYPE_LOGIN_DEEP_LINK
->
{
val
myself
=
client
.
me
()
// Just checking if the credentials worked.
if
(
myself
.
id
==
deepLinkUserId
)
{
Token
(
deepLinkUserId
,
deepLinkToken
)
}
else
{
throw
RocketChatAuthException
(
"Invalid Authentication Deep Link Credentials..."
)
}
}
else
->
{
else
->
{
throw
IllegalStateException
(
"Expected TYPE_LOGIN_USER_EMAIL, TYPE_LOGIN_CAS
or TYPE_LOGIN_OAUTH
"
)
throw
IllegalStateException
(
"Expected TYPE_LOGIN_USER_EMAIL, TYPE_LOGIN_CAS
, TYPE_LOGIN_OAUTH or TYPE_LOGIN_DEEP_LINK
"
)
}
}
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/authentication/login/ui/LoginFragment.kt
View file @
95a28de4
...
@@ -17,6 +17,7 @@ import android.widget.ScrollView
...
@@ -17,6 +17,7 @@ import android.widget.ScrollView
import
androidx.core.view.postDelayed
import
androidx.core.view.postDelayed
import
chat.rocket.android.BuildConfig
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.login.presentation.LoginPresenter
import
chat.rocket.android.authentication.login.presentation.LoginPresenter
import
chat.rocket.android.authentication.login.presentation.LoginView
import
chat.rocket.android.authentication.login.presentation.LoginView
import
chat.rocket.android.helper.KeyboardHelper
import
chat.rocket.android.helper.KeyboardHelper
...
@@ -27,6 +28,7 @@ import chat.rocket.android.webview.cas.ui.casWebViewIntent
...
@@ -27,6 +28,7 @@ import chat.rocket.android.webview.cas.ui.casWebViewIntent
import
chat.rocket.android.webview.oauth.ui.INTENT_OAUTH_CREDENTIAL_SECRET
import
chat.rocket.android.webview.oauth.ui.INTENT_OAUTH_CREDENTIAL_SECRET
import
chat.rocket.android.webview.oauth.ui.INTENT_OAUTH_CREDENTIAL_TOKEN
import
chat.rocket.android.webview.oauth.ui.INTENT_OAUTH_CREDENTIAL_TOKEN
import
chat.rocket.android.webview.oauth.ui.oauthWebViewIntent
import
chat.rocket.android.webview.oauth.ui.oauthWebViewIntent
import
chat.rocket.common.util.ifNull
import
dagger.android.support.AndroidSupportInjection
import
dagger.android.support.AndroidSupportInjection
import
kotlinx.android.synthetic.main.fragment_authentication_log_in.*
import
kotlinx.android.synthetic.main.fragment_authentication_log_in.*
import
javax.inject.Inject
import
javax.inject.Inject
...
@@ -41,14 +43,22 @@ class LoginFragment : Fragment(), LoginView {
...
@@ -41,14 +43,22 @@ class LoginFragment : Fragment(), LoginView {
areLoginOptionsNeeded
()
areLoginOptionsNeeded
()
}
}
private
var
isGlobalLayoutListenerSetUp
=
false
private
var
isGlobalLayoutListenerSetUp
=
false
private
var
deepLinkInfo
:
LoginDeepLinkInfo
?
=
null
companion
object
{
companion
object
{
fun
newInstance
()
=
LoginFragment
()
private
const
val
DEEP_LINK_INFO
=
"DeepLinkInfo"
fun
newInstance
(
deepLinkInfo
:
LoginDeepLinkInfo
?
=
null
)
=
LoginFragment
().
apply
{
arguments
=
Bundle
().
apply
{
putParcelable
(
DEEP_LINK_INFO
,
deepLinkInfo
)
}
}
}
}
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
AndroidSupportInjection
.
inject
(
this
)
deepLinkInfo
=
arguments
?.
getParcelable
(
DEEP_LINK_INFO
)
}
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
...
@@ -61,7 +71,11 @@ class LoginFragment : Fragment(), LoginView {
...
@@ -61,7 +71,11 @@ class LoginFragment : Fragment(), LoginView {
tintEditTextDrawableStart
()
tintEditTextDrawableStart
()
}
}
presenter
.
setupView
()
deepLinkInfo
?.
let
{
presenter
.
authenticadeWithDeepLink
(
it
)
}.
ifNull
{
presenter
.
setupView
()
}
}
}
override
fun
onDestroyView
()
{
override
fun
onDestroyView
()
{
...
...
app/src/main/java/chat/rocket/android/authentication/presentation/AuthenticationNavigator.kt
View file @
95a28de4
...
@@ -2,6 +2,7 @@ package chat.rocket.android.authentication.presentation
...
@@ -2,6 +2,7 @@ package chat.rocket.android.authentication.presentation
import
android.content.Intent
import
android.content.Intent
import
chat.rocket.android.R
import
chat.rocket.android.R
import
chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import
chat.rocket.android.authentication.login.ui.LoginFragment
import
chat.rocket.android.authentication.login.ui.LoginFragment
import
chat.rocket.android.authentication.registerusername.ui.RegisterUsernameFragment
import
chat.rocket.android.authentication.registerusername.ui.RegisterUsernameFragment
import
chat.rocket.android.authentication.signup.ui.SignupFragment
import
chat.rocket.android.authentication.signup.ui.SignupFragment
...
@@ -21,6 +22,12 @@ class AuthenticationNavigator(internal val activity: AuthenticationActivity) {
...
@@ -21,6 +22,12 @@ class AuthenticationNavigator(internal val activity: AuthenticationActivity) {
}
}
}
}
fun
toLogin
(
deepLinkInfo
:
LoginDeepLinkInfo
)
{
activity
.
addFragmentBackStack
(
"LoginFragment"
,
R
.
id
.
fragment_container
)
{
LoginFragment
.
newInstance
(
deepLinkInfo
)
}
}
fun
toTwoFA
(
username
:
String
,
password
:
String
)
{
fun
toTwoFA
(
username
:
String
,
password
:
String
)
{
activity
.
addFragmentBackStack
(
"TwoFAFragment"
,
R
.
id
.
fragment_container
)
{
activity
.
addFragmentBackStack
(
"TwoFAFragment"
,
R
.
id
.
fragment_container
)
{
TwoFAFragment
.
newInstance
(
username
,
password
)
TwoFAFragment
.
newInstance
(
username
,
password
)
...
...
app/src/main/java/chat/rocket/android/authentication/server/presentation/ServerPresenter.kt
View file @
95a28de4
package
chat.rocket.android.authentication.server.presentation
package
chat.rocket.android.authentication.server.presentation
import
chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
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.server.domain.GetAccountsInteractor
import
chat.rocket.android.server.domain.GetAccountsInteractor
import
chat.rocket.android.server.domain.RefreshSettingsInteractor
import
chat.rocket.android.server.domain.RefreshSettingsInteractor
...
@@ -18,6 +20,12 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
...
@@ -18,6 +20,12 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
private
val
getAccountsInteractor
:
GetAccountsInteractor
)
{
private
val
getAccountsInteractor
:
GetAccountsInteractor
)
{
fun
connect
(
server
:
String
)
{
fun
connect
(
server
:
String
)
{
connectToServer
(
server
)
{
navigator
.
toLogin
()
}
}
fun
connectToServer
(
server
:
String
,
block
:
()
->
Unit
)
{
if
(!
server
.
isValidUrl
())
{
if
(!
server
.
isValidUrl
())
{
view
.
showInvalidServerUrlMessage
()
view
.
showInvalidServerUrlMessage
()
}
else
{
}
else
{
...
@@ -33,17 +41,19 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
...
@@ -33,17 +41,19 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
try
{
try
{
refreshSettingsInteractor
.
refresh
(
server
)
refreshSettingsInteractor
.
refresh
(
server
)
serverInteractor
.
save
(
server
)
serverInteractor
.
save
(
server
)
navigator
.
toLogin
()
block
()
}
catch
(
ex
:
Exception
)
{
}
catch
(
ex
:
Exception
)
{
ex
.
message
?.
let
{
view
.
showMessage
(
ex
)
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
finally
{
}
finally
{
view
.
hideLoading
()
view
.
hideLoading
()
}
}
}
}
}
}
}
}
fun
deepLink
(
deepLinkInfo
:
LoginDeepLinkInfo
)
{
connectToServer
(
deepLinkInfo
.
url
)
{
navigator
.
toLogin
(
deepLinkInfo
)
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/server/ui/ServerFragment.kt
View file @
95a28de4
...
@@ -7,6 +7,7 @@ import android.view.View
...
@@ -7,6 +7,7 @@ import android.view.View
import
android.view.ViewGroup
import
android.view.ViewGroup
import
android.view.ViewTreeObserver
import
android.view.ViewTreeObserver
import
chat.rocket.android.R
import
chat.rocket.android.R
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
...
@@ -17,17 +18,26 @@ import javax.inject.Inject
...
@@ -17,17 +18,26 @@ 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
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
)
}
}
companion
object
{
companion
object
{
fun
newInstance
()
=
ServerFragment
()
private
const
val
DEEP_LINK_INFO
=
"DeepLinkInfo"
fun
newInstance
(
deepLinkInfo
:
LoginDeepLinkInfo
?)
=
ServerFragment
().
apply
{
arguments
=
Bundle
().
apply
{
putParcelable
(
DEEP_LINK_INFO
,
deepLinkInfo
)
}
}
}
}
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
AndroidSupportInjection
.
inject
(
this
)
deepLinkInfo
=
arguments
?.
getParcelable
(
DEEP_LINK_INFO
)
}
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
...
@@ -37,6 +47,10 @@ class ServerFragment : Fragment(), ServerView {
...
@@ -37,6 +47,10 @@ class ServerFragment : Fragment(), ServerView {
super
.
onViewCreated
(
view
,
savedInstanceState
)
super
.
onViewCreated
(
view
,
savedInstanceState
)
relative_layout
.
viewTreeObserver
.
addOnGlobalLayoutListener
(
layoutListener
)
relative_layout
.
viewTreeObserver
.
addOnGlobalLayoutListener
(
layoutListener
)
setupOnClickListener
()
setupOnClickListener
()
deepLinkInfo
?.
let
{
presenter
.
deepLink
(
it
)
}
}
}
override
fun
onDestroyView
()
{
override
fun
onDestroyView
()
{
...
...
app/src/main/java/chat/rocket/android/authentication/twofactor/ui/TwoFAFragment.kt
View file @
95a28de4
...
@@ -28,7 +28,7 @@ class TwoFAFragment : Fragment(), TwoFAView {
...
@@ -28,7 +28,7 @@ class TwoFAFragment : Fragment(), TwoFAView {
private
const
val
PASSWORD
=
"password"
private
const
val
PASSWORD
=
"password"
fun
newInstance
(
username
:
String
,
password
:
String
)
=
TwoFAFragment
().
apply
{
fun
newInstance
(
username
:
String
,
password
:
String
)
=
TwoFAFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
arguments
=
Bundle
(
2
).
apply
{
putString
(
USERNAME
,
username
)
putString
(
USERNAME
,
username
)
putString
(
PASSWORD
,
password
)
putString
(
PASSWORD
,
password
)
}
}
...
...
app/src/main/java/chat/rocket/android/authentication/ui/AuthenticationActivity.kt
View file @
95a28de4
...
@@ -6,10 +6,11 @@ import android.os.Bundle
...
@@ -6,10 +6,11 @@ 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.authentication.domain.model.LoginDeepLinkInfo
import
chat.rocket.android.authentication.domain.model.getLoginDeepLinkInfo
import
chat.rocket.android.authentication.presentation.AuthenticationPresenter
import
chat.rocket.android.authentication.presentation.AuthenticationPresenter
import
chat.rocket.android.authentication.server.ui.ServerFragment
import
chat.rocket.android.authentication.server.ui.ServerFragment
import
chat.rocket.android.util.extensions.addFragment
import
chat.rocket.android.util.extensions.addFragment
import
chat.rocket.android.util.extensions.launchUI
import
dagger.android.AndroidInjection
import
dagger.android.AndroidInjection
import
dagger.android.AndroidInjector
import
dagger.android.AndroidInjector
import
dagger.android.DispatchingAndroidInjector
import
dagger.android.DispatchingAndroidInjector
...
@@ -30,11 +31,13 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
...
@@ -30,11 +31,13 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
setTheme
(
R
.
style
.
AuthenticationTheme
)
setTheme
(
R
.
style
.
AuthenticationTheme
)
super
.
onCreate
(
savedInstanceState
)
super
.
onCreate
(
savedInstanceState
)
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
)
presenter
.
loadCredentials
(
newServer
)
{
authenticated
->
// if we got authenticadeWithDeepLink information, pass true to newServer also
presenter
.
loadCredentials
(
newServer
||
deepLinkInfo
!=
null
)
{
authenticated
->
if
(!
authenticated
)
{
if
(!
authenticated
)
{
showServerInput
(
savedInstanceState
)
showServerInput
(
savedInstanceState
,
deepLinkInfo
)
}
}
}
}
}
}
...
@@ -49,9 +52,9 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
...
@@ -49,9 +52,9 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
return
fragmentDispatchingAndroidInjector
return
fragmentDispatchingAndroidInjector
}
}
fun
showServerInput
(
savedInstanceState
:
Bundle
?)
{
fun
showServerInput
(
savedInstanceState
:
Bundle
?
,
deepLinkInfo
:
LoginDeepLinkInfo
?
)
{
addFragment
(
"ServerFragment"
,
R
.
id
.
fragment_container
)
{
addFragment
(
"ServerFragment"
,
R
.
id
.
fragment_container
)
{
ServerFragment
.
newInstance
()
ServerFragment
.
newInstance
(
deepLinkInfo
)
}
}
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
View file @
95a28de4
...
@@ -57,6 +57,10 @@ class ChatRoomAdapter(
...
@@ -57,6 +57,10 @@ class ChatRoomAdapter(
val
view
=
parent
.
inflate
(
R
.
layout
.
item_author_attachment
)
val
view
=
parent
.
inflate
(
R
.
layout
.
item_author_attachment
)
AuthorAttachmentViewHolder
(
view
,
actionsListener
,
reactionListener
)
AuthorAttachmentViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
}
BaseViewModel
.
ViewType
.
COLOR_ATTACHMENT
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
item_color_attachment
)
ColorAttachmentViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
else
->
{
else
->
{
throw
InvalidParameterException
(
"TODO - implement for ${viewType.toViewType()}"
)
throw
InvalidParameterException
(
"TODO - implement for ${viewType.toViewType()}"
)
}
}
...
@@ -97,6 +101,7 @@ class ChatRoomAdapter(
...
@@ -97,6 +101,7 @@ class ChatRoomAdapter(
is
UrlPreviewViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
UrlPreviewViewModel
)
is
UrlPreviewViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
UrlPreviewViewModel
)
is
MessageAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
MessageAttachmentViewModel
)
is
MessageAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
MessageAttachmentViewModel
)
is
AuthorAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
AuthorAttachmentViewModel
)
is
AuthorAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
AuthorAttachmentViewModel
)
is
ColorAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
ColorAttachmentViewModel
)
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/ColorAttachmentViewHolder.kt
0 → 100644
View file @
95a28de4
package
chat.rocket.android.chatroom.adapter
import
android.graphics.drawable.Drawable
import
android.support.v4.content.ContextCompat
import
android.text.method.LinkMovementMethod
import
android.view.View
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.viewmodel.ColorAttachmentViewModel
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
kotlinx.android.synthetic.main.item_color_attachment.view.*
class
ColorAttachmentViewHolder
(
itemView
:
View
,
listener
:
BaseViewHolder
.
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
ColorAttachmentViewModel
>(
itemView
,
listener
,
reactionListener
)
{
val
drawable
:
Drawable
?
=
ContextCompat
.
getDrawable
(
itemView
.
context
,
R
.
drawable
.
quote_vertical_bar
)
init
{
with
(
itemView
)
{
setupActionMenu
(
attachment_text
)
setupActionMenu
(
color_attachment_container
)
attachment_text
.
movementMethod
=
LinkMovementMethod
()
}
}
override
fun
bindViews
(
data
:
ColorAttachmentViewModel
)
{
with
(
itemView
)
{
drawable
?.
let
{
quote_bar
.
background
=
drawable
.
mutate
().
apply
{
setTint
(
data
.
color
)
}
attachment_text
.
text
=
data
.
text
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
95a28de4
...
@@ -233,9 +233,9 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
...
@@ -233,9 +233,9 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
// if y is positive the keyboard is up else it's down
// if y is positive the keyboard is up else it's down
recycler_view
.
post
{
recycler_view
.
post
{
if
(
y
>
0
||
Math
.
abs
(
verticalScrollOffset
.
get
())
>=
Math
.
abs
(
y
))
{
if
(
y
>
0
||
Math
.
abs
(
verticalScrollOffset
.
get
())
>=
Math
.
abs
(
y
))
{
recycler_view
.
scrollBy
(
0
,
y
)
ui
{
recycler_view
.
scrollBy
(
0
,
y
)
}
}
else
{
}
else
{
recycler_view
.
scrollBy
(
0
,
verticalScrollOffset
.
get
())
ui
{
recycler_view
.
scrollBy
(
0
,
verticalScrollOffset
.
get
())
}
}
}
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/BaseViewModel.kt
View file @
95a28de4
...
@@ -22,7 +22,8 @@ interface BaseViewModel<out T> {
...
@@ -22,7 +22,8 @@ interface BaseViewModel<out T> {
VIDEO_ATTACHMENT
(
4
),
VIDEO_ATTACHMENT
(
4
),
AUDIO_ATTACHMENT
(
5
),
AUDIO_ATTACHMENT
(
5
),
MESSAGE_ATTACHMENT
(
6
),
MESSAGE_ATTACHMENT
(
6
),
AUTHOR_ATTACHMENT
(
7
)
AUTHOR_ATTACHMENT
(
7
),
COLOR_ATTACHMENT
(
8
)
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/ColorAttachmentViewModel.kt
0 → 100644
View file @
95a28de4
package
chat.rocket.android.chatroom.viewmodel
import
chat.rocket.android.R
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.attachment.ColorAttachment
data class
ColorAttachmentViewModel
(
override
val
attachmentUrl
:
String
,
val
id
:
Long
,
val
color
:
Int
,
val
text
:
CharSequence
,
override
val
message
:
Message
,
override
val
rawData
:
ColorAttachment
,
override
val
messageId
:
String
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
,
override
var
preview
:
Message
?
=
null
,
override
var
isTemporary
:
Boolean
=
false
)
:
BaseAttachmentViewModel
<
ColorAttachment
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
COLOR_ATTACHMENT
.
viewType
override
val
layoutId
:
Int
get
()
=
R
.
layout
.
item_color_attachment
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
View file @
95a28de4
...
@@ -5,6 +5,7 @@ import android.content.Context
...
@@ -5,6 +5,7 @@ import android.content.Context
import
android.graphics.Color
import
android.graphics.Color
import
android.graphics.Typeface
import
android.graphics.Typeface
import
android.support.v4.content.ContextCompat
import
android.support.v4.content.ContextCompat
import
android.text.Html
import
android.text.SpannableStringBuilder
import
android.text.SpannableStringBuilder
import
android.text.style.ForegroundColorSpan
import
android.text.style.ForegroundColorSpan
import
android.text.style.StyleSpan
import
android.text.style.StyleSpan
...
@@ -106,10 +107,23 @@ class ViewModelMapper @Inject constructor(private val context: Context,
...
@@ -106,10 +107,23 @@ class ViewModelMapper @Inject constructor(private val context: Context,
is
FileAttachment
->
mapFileAttachment
(
message
,
attachment
)
is
FileAttachment
->
mapFileAttachment
(
message
,
attachment
)
is
MessageAttachment
->
mapMessageAttachment
(
message
,
attachment
)
is
MessageAttachment
->
mapMessageAttachment
(
message
,
attachment
)
is
AuthorAttachment
->
mapAuthorAttachment
(
message
,
attachment
)
is
AuthorAttachment
->
mapAuthorAttachment
(
message
,
attachment
)
is
ColorAttachment
->
mapColorAttachment
(
message
,
attachment
)
else
->
null
else
->
null
}
}
}
}
private
suspend
fun
mapColorAttachment
(
message
:
Message
,
attachment
:
ColorAttachment
):
BaseViewModel
<
*
>?
{
return
with
(
attachment
)
{
val
content
=
stripMessageQuotes
(
message
)
val
id
=
attachmentId
(
message
,
attachment
)
ColorAttachmentViewModel
(
attachmentUrl
=
url
,
id
=
id
,
color
=
color
.
color
,
text
=
text
,
message
=
message
,
rawData
=
attachment
,
messageId
=
message
.
id
,
reactions
=
getReactions
(
message
),
preview
=
message
.
copy
(
message
=
content
.
message
))
}
}
private
suspend
fun
mapAuthorAttachment
(
message
:
Message
,
attachment
:
AuthorAttachment
):
AuthorAttachmentViewModel
{
private
suspend
fun
mapAuthorAttachment
(
message
:
Message
,
attachment
:
AuthorAttachment
):
AuthorAttachmentViewModel
{
return
with
(
attachment
)
{
return
with
(
attachment
)
{
val
content
=
stripMessageQuotes
(
message
)
val
content
=
stripMessageQuotes
(
message
)
...
...
app/src/main/java/chat/rocket/android/core/behaviours/MessageView.kt
View file @
95a28de4
package
chat.rocket.android.core.behaviours
package
chat.rocket.android.core.behaviours
import
android.support.annotation.StringRes
import
android.support.annotation.StringRes
import
chat.rocket.common.util.ifNull
interface
MessageView
{
interface
MessageView
{
...
@@ -14,4 +15,12 @@ interface MessageView {
...
@@ -14,4 +15,12 @@ interface MessageView {
fun
showMessage
(
message
:
String
)
fun
showMessage
(
message
:
String
)
fun
showGenericErrorMessage
()
fun
showGenericErrorMessage
()
}
fun
MessageView
.
showMessage
(
ex
:
Exception
)
{
ex
.
message
?.
let
{
showMessage
(
it
)
}.
ifNull
{
showGenericErrorMessage
()
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt
View file @
95a28de4
...
@@ -16,6 +16,7 @@ import chat.rocket.android.authentication.infraestructure.SharedPreferencesMulti
...
@@ -16,6 +16,7 @@ import chat.rocket.android.authentication.infraestructure.SharedPreferencesMulti
import
chat.rocket.android.authentication.infraestructure.SharedPreferencesTokenRepository
import
chat.rocket.android.authentication.infraestructure.SharedPreferencesTokenRepository
import
chat.rocket.android.chatroom.service.MessageService
import
chat.rocket.android.chatroom.service.MessageService
import
chat.rocket.android.dagger.qualifier.ForFresco
import
chat.rocket.android.dagger.qualifier.ForFresco
import
chat.rocket.android.dagger.qualifier.ForMessages
import
chat.rocket.android.helper.FrescoAuthInterceptor
import
chat.rocket.android.helper.FrescoAuthInterceptor
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.LocalRepository
...
@@ -73,7 +74,7 @@ class AppModule {
...
@@ -73,7 +74,7 @@ class AppModule {
@Provides
@Provides
@Singleton
@Singleton
fun
provideRocketChatDatabase
(
context
:
Application
):
RocketChatDatabase
{
fun
provideRocketChatDatabase
(
context
:
Application
):
RocketChatDatabase
{
return
Room
.
databaseBuilder
(
context
,
RocketChatDatabase
::
class
.
java
,
"rocketchat-db"
).
build
()
return
Room
.
databaseBuilder
(
context
.
applicationContext
,
RocketChatDatabase
::
class
.
java
,
"rocketchat-db"
).
build
()
}
}
@Provides
@Provides
...
@@ -168,9 +169,14 @@ class AppModule {
...
@@ -168,9 +169,14 @@ class AppModule {
}
}
@Provides
@Provides
fun
provideSharedPreferences
(
context
:
Application
):
SharedPreferences
{
fun
provideSharedPreferences
(
context
:
Application
)
=
return
context
.
getSharedPreferences
(
"rocket.chat"
,
Context
.
MODE_PRIVATE
)
context
.
getSharedPreferences
(
"rocket.chat"
,
Context
.
MODE_PRIVATE
)
}
@Provides
@ForMessages
fun
provideMessagesSharedPreferences
(
context
:
Application
)
=
context
.
getSharedPreferences
(
"messages"
,
Context
.
MODE_PRIVATE
)
@Provides
@Provides
@Singleton
@Singleton
...
@@ -225,8 +231,10 @@ class AppModule {
...
@@ -225,8 +231,10 @@ class AppModule {
@Provides
@Provides
@Singleton
@Singleton
fun
provideMessageRepository
(
context
:
Application
,
moshi
:
Moshi
,
currentServerInteractor
:
GetCurrentServerInteractor
):
MessagesRepository
{
fun
provideMessageRepository
(
context
:
Application
,
val
preferences
=
context
.
getSharedPreferences
(
"messages"
,
Context
.
MODE_PRIVATE
)
@ForMessages
preferences
:
SharedPreferences
,
moshi
:
Moshi
,
currentServerInteractor
:
GetCurrentServerInteractor
):
MessagesRepository
{
return
SharedPreferencesMessagesRepository
(
preferences
,
moshi
,
currentServerInteractor
)
return
SharedPreferencesMessagesRepository
(
preferences
,
moshi
,
currentServerInteractor
)
}
}
...
...
app/src/main/java/chat/rocket/android/dagger/qualifier/ForMessages.kt
0 → 100644
View file @
95a28de4
package
chat.rocket.android.dagger.qualifier
import
javax.inject.Qualifier
/**
* Created by luciofm on 4/14/18.
*/
@Qualifier
@Retention
(
AnnotationRetention
.
RUNTIME
)
annotation
class
ForMessages
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt
View file @
95a28de4
...
@@ -41,7 +41,7 @@ class MainPresenter @Inject constructor(
...
@@ -41,7 +41,7 @@ class MainPresenter @Inject constructor(
private
val
factory
:
RocketChatClientFactory
,
private
val
factory
:
RocketChatClientFactory
,
getSettingsInteractor
:
GetSettingsInteractor
,
getSettingsInteractor
:
GetSettingsInteractor
,
managerFactory
:
ConnectionManagerFactory
managerFactory
:
ConnectionManagerFactory
)
:
CheckServerPresenter
(
strategy
,
client
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
,
view
=
view
)
{
)
:
CheckServerPresenter
(
strategy
,
factory
,
view
=
view
)
{
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
manager
=
managerFactory
.
create
(
currentServer
)
private
val
manager
=
managerFactory
.
create
(
currentServer
)
private
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
private
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
...
@@ -56,7 +56,7 @@ class MainPresenter @Inject constructor(
...
@@ -56,7 +56,7 @@ class MainPresenter @Inject constructor(
fun
toSettings
()
=
navigator
.
toSettings
()
fun
toSettings
()
=
navigator
.
toSettings
()
fun
loadCurrentInfo
()
{
fun
loadCurrentInfo
()
{
checkServerInfo
()
checkServerInfo
(
currentServer
)
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
try
{
try
{
val
me
=
retryIO
(
"me"
)
{
val
me
=
retryIO
(
"me"
)
{
...
...
app/src/main/java/chat/rocket/android/server/domain/RefreshSettingsInteractor.kt
View file @
95a28de4
package
chat.rocket.android.server.domain
package
chat.rocket.android.server.domain
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.retryIO
import
chat.rocket.core.internal.rest.settings
import
chat.rocket.core.internal.rest.settings
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.async
import
kotlinx.coroutines.experimental.async
...
@@ -27,7 +28,9 @@ class RefreshSettingsInteractor @Inject constructor(private val factory: RocketC
...
@@ -27,7 +28,9 @@ class RefreshSettingsInteractor @Inject constructor(private val factory: RocketC
suspend
fun
refresh
(
server
:
String
)
{
suspend
fun
refresh
(
server
:
String
)
{
withContext
(
CommonPool
)
{
withContext
(
CommonPool
)
{
factory
.
create
(
server
).
let
{
client
->
factory
.
create
(
server
).
let
{
client
->
val
settings
=
client
.
settings
(*
settingsFilter
)
val
settings
=
retryIO
(
description
=
"settings"
,
times
=
5
)
{
client
.
settings
(*
settingsFilter
)
}
repository
.
save
(
server
,
settings
)
repository
.
save
(
server
,
settings
)
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/server/presentation/CheckServerPresenter.kt
View file @
95a28de4
...
@@ -3,33 +3,40 @@ package chat.rocket.android.server.presentation
...
@@ -3,33 +3,40 @@ package chat.rocket.android.server.presentation
import
chat.rocket.android.BuildConfig
import
chat.rocket.android.BuildConfig
import
chat.rocket.android.authentication.server.presentation.VersionCheckView
import
chat.rocket.android.authentication.server.presentation.VersionCheckView
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.VersionInfo
import
chat.rocket.android.util.VersionInfo
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.retryIO
import
chat.rocket.android.util.retryIO
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.serverInfo
import
chat.rocket.core.internal.rest.serverInfo
import
kotlinx.coroutines.experimental.Deferred
import
kotlinx.coroutines.experimental.Job
import
kotlinx.coroutines.experimental.async
import
timber.log.Timber
import
timber.log.Timber
abstract
class
CheckServerPresenter
constructor
(
private
val
strategy
:
CancelStrategy
,
abstract
class
CheckServerPresenter
constructor
(
private
val
strategy
:
CancelStrategy
,
private
val
client
:
RocketChatClient
,
private
val
factory
:
RocketChatClientFactory
,
private
val
view
:
VersionCheckView
)
{
private
val
view
:
VersionCheckView
)
{
internal
fun
checkServerInfo
()
{
private
lateinit
var
currentServer
:
String
launchUI
(
strategy
)
{
private
val
client
:
RocketChatClient
by
lazy
{
factory
.
create
(
currentServer
)
}
internal
fun
checkServerInfo
(
serverUrl
:
String
):
Job
{
return
launchUI
(
strategy
)
{
try
{
try
{
val
serverInfo
=
retryIO
(
description
=
"serverInfo"
,
times
=
5
)
{
client
.
serverInfo
()
}
val
version
=
checkServerVersion
(
serverUrl
).
await
()
val
thisServerVersion
=
serverInfo
.
version
when
(
version
)
{
val
isRequiredVersion
=
isRequiredServerVersion
(
thisServerVersion
)
is
Version
.
VersionOk
->
{
val
isRecommendedVersion
=
isRecommendedServerVersion
(
thisServerVersion
)
Timber
.
i
(
"Your version is nice! (Requires: 0.62.0, Yours: ${version.version})"
)
if
(
isRequiredVersion
)
{
}
if
(
isRecommendedVersion
)
{
is
Version
.
RecommendedVersionWarning
->
{
Timber
.
i
(
"Your version is nice! (Requires: 0.62.0, Yours: $thisServerVersion)"
)
Timber
.
i
(
"Your server ${version.version} is bellow recommended version ${BuildConfig.RECOMMENDED_SERVER_VERSION}"
)
}
else
{
view
.
alertNotRecommendedVersion
()
view
.
alertNotRecommendedVersion
()
}
}
}
else
{
is
Version
.
OutOfDateError
->
{
if
(!
isRecommendedVersion
)
{
Timber
.
i
(
"Oops. Looks like your server ${version.version} is out-of-date! Minimum server version required ${BuildConfig.REQUIRED_SERVER_VERSION}!"
)
view
.
blockAndAlertNotRequiredVersion
()
view
.
blockAndAlertNotRequiredVersion
()
Timber
.
i
(
"Oops. Looks like your server is out-of-date! Minimum server version required ${BuildConfig.REQUIRED_SERVER_VERSION}!"
)
}
}
}
}
}
catch
(
ex
:
Exception
)
{
}
catch
(
ex
:
Exception
)
{
...
@@ -38,6 +45,26 @@ abstract class CheckServerPresenter constructor(private val strategy: CancelStra
...
@@ -38,6 +45,26 @@ abstract class CheckServerPresenter constructor(private val strategy: CancelStra
}
}
}
}
internal
fun
checkServerVersion
(
serverUrl
:
String
):
Deferred
<
Version
>
{
currentServer
=
serverUrl
return
async
{
val
serverInfo
=
retryIO
(
description
=
"serverInfo"
,
times
=
5
)
{
client
.
serverInfo
()
}
val
thisServerVersion
=
serverInfo
.
version
val
isRequiredVersion
=
isRequiredServerVersion
(
thisServerVersion
)
val
isRecommendedVersion
=
isRecommendedServerVersion
(
thisServerVersion
)
if
(
isRequiredVersion
)
{
if
(
isRecommendedVersion
)
{
Timber
.
i
(
"Your version is nice! (Requires: 0.62.0, Yours: $thisServerVersion)"
)
return
@async
Version
.
VersionOk
(
thisServerVersion
)
}
else
{
return
@async
Version
.
RecommendedVersionWarning
(
thisServerVersion
)
}
}
else
{
return
@async
Version
.
OutOfDateError
(
thisServerVersion
)
}
}
}
private
fun
isRequiredServerVersion
(
version
:
String
):
Boolean
{
private
fun
isRequiredServerVersion
(
version
:
String
):
Boolean
{
return
isMinimumVersion
(
version
,
getVersionDistilled
(
BuildConfig
.
REQUIRED_SERVER_VERSION
))
return
isMinimumVersion
(
version
,
getVersionDistilled
(
BuildConfig
.
REQUIRED_SERVER_VERSION
))
}
}
...
@@ -92,4 +119,10 @@ abstract class CheckServerPresenter constructor(private val strategy: CancelStra
...
@@ -92,4 +119,10 @@ abstract class CheckServerPresenter constructor(private val strategy: CancelStra
0
0
}
}
}
}
sealed
class
Version
(
val
version
:
String
)
{
data class
VersionOk
(
private
val
currentVersion
:
String
)
:
Version
(
currentVersion
)
data class
RecommendedVersionWarning
(
private
val
currentVersion
:
String
)
:
Version
(
currentVersion
)
data class
OutOfDateError
(
private
val
currentVersion
:
String
)
:
Version
(
currentVersion
)
}
}
}
\ No newline at end of file
app/src/main/res/layout/fragment_profile.xml
View file @
95a28de4
...
@@ -8,53 +8,61 @@
...
@@ -8,53 +8,61 @@
android:focusableInTouchMode=
"true"
android:focusableInTouchMode=
"true"
tools:context=
".profile.ui.ProfileFragment"
>
tools:context=
".profile.ui.ProfileFragment"
>
<LinearLayout
<ScrollView
android:id=
"@+id/profile_container"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
>
android:gravity=
"center"
android:orientation=
"vertical"
android:visibility=
"gone"
>
<include
<LinearLayout
android:id=
"@+id/layout_avatar_profile"
android:id=
"@+id/profile_container"
layout=
"@layout/avatar_profile"
android:layout_width=
"match_parent"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"32dp"
/>
android:gravity=
"center"
android:orientation=
"vertical"
android:visibility=
"gone"
tools:visibility=
"visible"
>
<include
android:id=
"@+id/layout_avatar_profile"
layout=
"@layout/avatar_profile"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"32dp"
/>
<EditText
android:id=
"@+id/text_name"
style=
"@style/Profile.EditText"
android:layout_marginTop=
"32dp"
android:drawableStart=
"@drawable/ic_person_black_24dp"
android:hint=
"@string/msg_name"
android:inputType=
"textCapWords"
/>
<EditText
<EditText
android:id=
"@+id/text_
name"
android:id=
"@+id/text_user
name"
style=
"@style/Profile.EditText"
style=
"@style/Profile.EditText"
android:layout_marginTop=
"32
dp"
android:layout_marginTop=
"16
dp"
android:drawableStart=
"@drawable/ic_person
_black_24dp"
android:drawableStart=
"@drawable/ic_at
_black_24dp"
android:hint=
"@string/msg_
name"
android:hint=
"@string/msg_user
name"
android:inputType=
"textCapWords
"
/>
android:inputType=
"text
"
/>
<EditText
<EditText
android:id=
"@+id/text_username
"
android:id=
"@+id/text_email
"
style=
"@style/Profile.EditText"
style=
"@style/Profile.EditText"
android:layout_marginTop=
"16dp"
android:layout_marginTop=
"16dp"
android:drawableStart=
"@drawable/ic_at
_black_24dp"
android:drawableStart=
"@drawable/ic_email
_black_24dp"
android:hint=
"@string/msg_username
"
android:hint=
"@string/msg_email
"
android:inputType=
"text
"
/>
android:inputType=
"textEmailAddress
"
/>
<EditText
<EditText
android:id=
"@+id/text_email"
android:id=
"@+id/text_avatar_url"
style=
"@style/Profile.EditText"
style=
"@style/Profile.EditText"
android:layout_marginTop=
"16dp"
android:layout_marginTop=
"16dp"
android:drawableStart=
"@drawable/ic_email_black_24dp"
android:drawableStart=
"@drawable/ic_link_black_24dp"
android:hint=
"@string/msg_email"
android:hint=
"@string/msg_avatar_url"
android:inputType=
"textEmailAddress"
/>
android:inputType=
"text"
android:layout_marginBottom=
"16dp"
/>
</LinearLayout>
<EditText
</ScrollView>
android:id=
"@+id/text_avatar_url"
style=
"@style/Profile.EditText"
android:layout_marginTop=
"16dp"
android:drawableStart=
"@drawable/ic_link_black_24dp"
android:hint=
"@string/msg_avatar_url"
android:inputType=
"text"
/>
</LinearLayout>
<com.wang.avi.AVLoadingIndicatorView
<com.wang.avi.AVLoadingIndicatorView
android:id=
"@+id/view_loading"
android:id=
"@+id/view_loading"
...
...
app/src/main/res/layout/item_color_attachment.xml
0 → 100644
View file @
95a28de4
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/color_attachment_container"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"?android:attr/selectableItemBackground"
android:clickable=
"true"
android:focusable=
"true"
android:paddingBottom=
"@dimen/message_item_top_and_bottom_padding"
android:paddingEnd=
"@dimen/screen_edge_left_and_right_padding"
android:paddingStart=
"@dimen/screen_edge_left_and_right_padding"
android:paddingTop=
"@dimen/message_item_top_and_bottom_padding"
>
<View
android:id=
"@+id/quote_bar"
android:layout_width=
"4dp"
android:layout_height=
"0dp"
android:layout_marginStart=
"56dp"
android:background=
"@drawable/quote_vertical_bar"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toTopOf=
"@id/recycler_view_reactions"
/>
<TextView
android:id=
"@+id/attachment_text"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"8dp"
android:textAppearance=
"@style/TextAppearance.AppCompat.Body1"
android:autoLink=
"web"
app:layout_constraintStart_toEndOf=
"@id/quote_bar"
app:layout_constraintEnd_toEndOf=
"parent"
tools:text=
"#5571 - User profile from SSO must not have password change option"
/>
<include
layout=
"@layout/layout_reactions"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
app:layout_constraintStart_toStartOf=
"@id/quote_bar"
app:layout_constraintTop_toBottomOf=
"@id/attachment_text"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/xml/backup_config.xml
0 → 100644
View file @
95a28de4
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content
xmlns:tools=
"http://schemas.android.com/tools"
>
<include
domain=
"sharedpref"
path=
"."
/>
<exclude
domain=
"sharedpref"
path=
"messages.xml"
tools:ignore=
"FullBackupContent"
/>
<exclude
domain=
"file"
path=
"instant-run"
tools:ignore=
"FullBackupContent"
/>
</full-backup-content>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment