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
4b95f252
Unverified
Commit
4b95f252
authored
Apr 05, 2018
by
Rafael Kellermann Streit
Committed by
GitHub
Apr 05, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1030 from RocketChat/fix/crash-fixes
[FIX] batch of crash fixes from beta3
parents
6f0cc896
a6c3aca8
Changes
26
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
325 additions
and
263 deletions
+325
-263
RocketChatApplication.kt
...ain/java/chat/rocket/android/app/RocketChatApplication.kt
+5
-4
LoginPresenter.kt
...droid/authentication/login/presentation/LoginPresenter.kt
+29
-28
RegisterUsernamePresenter.kt
...egisterusername/presentation/RegisterUsernamePresenter.kt
+9
-5
ServerPresenter.kt
...oid/authentication/server/presentation/ServerPresenter.kt
+2
-2
SignupPresenter.kt
...oid/authentication/signup/presentation/SignupPresenter.kt
+13
-11
TwoFAPresenter.kt
...d/authentication/twofactor/presentation/TwoFAPresenter.kt
+9
-6
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+74
-41
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+53
-42
ViewModelMapper.kt
...chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
+2
-2
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+5
-2
ChatRoomsAdapter.kt
...java/chat/rocket/android/chatrooms/ui/ChatRoomsAdapter.kt
+2
-2
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+6
-5
OauthHelper.kt
app/src/main/java/chat/rocket/android/helper/OauthHelper.kt
+5
-3
UrlHelper.kt
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
+0
-74
MainPresenter.kt
...va/chat/rocket/android/main/presentation/MainPresenter.kt
+10
-5
NavHeaderViewModelMapper.kt
...rocket/android/main/viewmodel/NavHeaderViewModelMapper.kt
+4
-3
MembersPresenter.kt
...t/rocket/android/members/presentation/MembersPresenter.kt
+4
-1
MemberViewModel.kt
.../chat/rocket/android/members/viewmodel/MemberViewModel.kt
+2
-2
ProfilePresenter.kt
...t/rocket/android/profile/presentation/ProfilePresenter.kt
+6
-5
FirebaseTokenService.kt
...ain/java/chat/rocket/android/push/FirebaseTokenService.kt
+0
-1
CheckServerPresenter.kt
...ocket/android/server/presentation/CheckServerPresenter.kt
+18
-13
PasswordPresenter.kt
...droid/settings/password/presentation/PasswordPresenter.kt
+5
-1
IO.kt
app/src/main/java/chat/rocket/android/util/IO.kt
+29
-0
RocketChatClient.kt
...a/chat/rocket/android/util/extensions/RocketChatClient.kt
+4
-1
String.kt
...c/main/java/chat/rocket/android/util/extensions/String.kt
+25
-0
Uri.kt
app/src/main/java/chat/rocket/android/util/extensions/Uri.kt
+4
-4
No files found.
app/src/main/java/chat/rocket/android/app/RocketChatApplication.kt
View file @
4b95f252
...
...
@@ -18,10 +18,11 @@ import chat.rocket.android.app.migration.model.RealmUser
import
chat.rocket.android.authentication.domain.model.toToken
import
chat.rocket.android.dagger.DaggerAppComponent
import
chat.rocket.android.helper.CrashlyticsTree
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.serverLogoUrl
import
chat.rocket.android.widget.emoji.EmojiRepository
import
chat.rocket.common.model.Token
import
chat.rocket.core.model.Value
...
...
@@ -148,12 +149,12 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje
private
fun
migrateServerInfo
(
url
:
String
,
authToken
:
String
,
settings
:
PublicSettings
,
user
:
RealmUser
)
{
val
userId
=
user
.
_id
val
avatar
=
UrlHelper
.
getAvatarUrl
(
url
,
user
.
username
!!
)
val
avatar
=
url
.
avatarUrl
(
user
.
username
!!
)
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
url
,
it
)
url
.
serverLogoUrl
(
it
)
}
val
logo
=
settings
.
wideTile
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
url
,
it
)
url
.
serverLogoUrl
(
it
)
}
val
account
=
Account
(
url
,
icon
,
logo
,
user
.
username
!!
,
avatar
)
launch
(
CommonPool
)
{
...
...
app/src/main/java/chat/rocket/android/authentication/login/presentation/LoginPresenter.kt
View file @
4b95f252
package
chat.rocket.android.authentication.login.presentation
import
chat.rocket.android.BuildConfig
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.NetworkHelper
import
chat.rocket.android.helper.OauthHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.presentation.CheckServerPresenter
import
chat.rocket.android.util.VersionInfo
import
chat.rocket.android.util.extensions.*
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatTwoFactorException
import
chat.rocket.common.model.Token
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.*
import
chat.rocket.core.model.Myself
import
kotlinx.coroutines.experimental.delay
import
timber.log.Timber
import
java.util.concurrent.TimeUnit
...
...
@@ -103,7 +100,7 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
private
fun
setupCasView
()
{
if
(
settings
.
isCasAuthenticationEnabled
())
{
val
token
=
generateRandomString
(
17
)
view
.
setupCasButtonListener
(
UrlHelper
.
getCasUrl
(
settings
.
casLoginUrl
(),
currentServer
,
token
),
token
)
view
.
setupCasButtonListener
(
settings
.
casLoginUrl
().
casUrl
(
currentServer
,
token
),
token
)
view
.
showCasButton
()
}
}
...
...
@@ -118,7 +115,9 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
private
fun
setupOauthServicesView
()
{
launchUI
(
strategy
)
{
try
{
val
services
=
client
.
settingsOauth
().
services
val
services
=
retryIO
(
"settingsOauth()"
)
{
client
.
settingsOauth
().
services
}
if
(
services
.
isNotEmpty
())
{
val
state
=
"{\"loginStyle\":\"popup\",\"credentialToken\":\"${generateRandomString(40)}\",\"isCordova\":true}"
.
encodeToBase64
()
var
totalSocialAccountsEnabled
=
0
...
...
@@ -195,30 +194,32 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
view
.
disableUserInput
()
view
.
showLoading
()
try
{
val
token
=
when
(
loginType
)
{
TYPE_LOGIN_USER_EMAIL
->
{
if
(
usernameOrEmail
.
isEmail
())
{
client
.
loginWithEmail
(
usernameOrEmail
,
password
)
}
else
{
if
(
settings
.
isLdapAuthenticationEnabled
())
{
client
.
loginWithLdap
(
usernameOrEmail
,
password
)
val
token
=
retryIO
(
"login"
)
{
when
(
loginType
)
{
TYPE_LOGIN_USER_EMAIL
->
{
if
(
usernameOrEmail
.
isEmail
())
{
client
.
loginWithEmail
(
usernameOrEmail
,
password
)
}
else
{
client
.
login
(
usernameOrEmail
,
password
)
if
(
settings
.
isLdapAuthenticationEnabled
())
{
client
.
loginWithLdap
(
usernameOrEmail
,
password
)
}
else
{
client
.
login
(
usernameOrEmail
,
password
)
}
}
}
}
TYPE_LOGIN_CAS
->
{
delay
(
3
,
TimeUnit
.
SECONDS
)
client
.
loginWithCas
(
credentialToken
)
}
TYPE_LOGIN_OAUTH
->
{
client
.
loginWithOauth
(
credentialToken
,
credentialSecret
)
}
else
->
{
throw
IllegalStateException
(
"Expected TYPE_LOGIN_USER_EMAIL, TYPE_LOGIN_CAS or TYPE_LOGIN_OAUTH"
)
TYPE_LOGIN_CAS
->
{
delay
(
3
,
TimeUnit
.
SECONDS
)
client
.
loginWithCas
(
credentialToken
)
}
TYPE_LOGIN_OAUTH
->
{
client
.
loginWithOauth
(
credentialToken
,
credentialSecret
)
}
else
->
{
throw
IllegalStateException
(
"Expected TYPE_LOGIN_USER_EMAIL, TYPE_LOGIN_CAS or TYPE_LOGIN_OAUTH"
)
}
}
}
val
username
=
client
.
me
().
username
val
username
=
retryIO
(
"me()"
)
{
client
.
me
().
username
}
if
(
username
!=
null
)
{
localRepository
.
save
(
LocalRepository
.
CURRENT_USERNAME_KEY
,
username
)
saveAccount
(
username
)
...
...
@@ -258,12 +259,12 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
private
suspend
fun
saveAccount
(
username
:
String
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
currentServer
.
serverLogoUrl
(
it
)
}
val
logo
=
settings
.
wideTile
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
currentServer
.
serverLogoUrl
(
it
)
}
val
thumb
=
UrlHelper
.
getAvatarUrl
(
currentServer
,
username
)
val
thumb
=
currentServer
.
avatarUrl
(
username
)
val
account
=
Account
(
currentServer
,
icon
,
logo
,
username
,
thumb
)
saveAccountInteractor
.
save
(
account
)
}
...
...
app/src/main/java/chat/rocket/android/authentication/registerusername/presentation/RegisterUsernamePresenter.kt
View file @
4b95f252
...
...
@@ -3,13 +3,15 @@ package chat.rocket.android.authentication.registerusername.presentation
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.NetworkHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.extensions.registerPushToken
import
chat.rocket.android.util.extensions.serverLogoUrl
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.Token
import
chat.rocket.common.util.ifNull
...
...
@@ -41,7 +43,9 @@ class RegisterUsernamePresenter @Inject constructor(
if
(
NetworkHelper
.
hasInternetAccess
())
{
view
.
showLoading
()
try
{
val
me
=
client
.
updateOwnBasicInformation
(
username
=
username
)
val
me
=
retryIO
(
"updateOwnBasicInformation(username = $username)"
)
{
client
.
updateOwnBasicInformation
(
username
=
username
)
}
val
registeredUsername
=
me
.
username
if
(
registeredUsername
!=
null
)
{
saveAccount
(
registeredUsername
)
...
...
@@ -75,12 +79,12 @@ class RegisterUsernamePresenter @Inject constructor(
private
suspend
fun
saveAccount
(
username
:
String
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
currentServer
.
serverLogoUrl
(
it
)
}
val
logo
=
settings
.
wideTile
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
currentServer
.
serverLogoUrl
(
it
)
}
val
thumb
=
UrlHelper
.
getAvatarUrl
(
currentServer
,
username
)
val
thumb
=
currentServer
.
avatarUrl
(
username
)
val
account
=
Account
(
currentServer
,
icon
,
logo
,
username
,
thumb
)
saveAccountInteractor
.
save
(
account
)
}
...
...
app/src/main/java/chat/rocket/android/authentication/server/presentation/ServerPresenter.kt
View file @
4b95f252
...
...
@@ -3,10 +3,10 @@ package chat.rocket.android.authentication.server.presentation
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.NetworkHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.server.domain.GetAccountsInteractor
import
chat.rocket.android.server.domain.RefreshSettingsInteractor
import
chat.rocket.android.server.domain.SaveCurrentServerInteractor
import
chat.rocket.android.util.extensions.isValidUrl
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.common.util.ifNull
import
javax.inject.Inject
...
...
@@ -18,7 +18,7 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
private
val
refreshSettingsInteractor
:
RefreshSettingsInteractor
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
)
{
fun
connect
(
server
:
String
)
{
if
(!
UrlHelper
.
isValidUrl
(
server
))
{
if
(!
server
.
isValidUrl
(
))
{
view
.
showInvalidServerUrlMessage
()
}
else
{
launchUI
(
strategy
)
{
...
...
app/src/main/java/chat/rocket/android/authentication/signup/presentation/SignupPresenter.kt
View file @
4b95f252
...
...
@@ -3,20 +3,22 @@ package chat.rocket.android.authentication.signup.presentation
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.NetworkHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.main.viewmodel.NavHeaderViewModel
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.extensions.privacyPolicyUrl
import
chat.rocket.android.util.extensions.registerPushToken
import
chat.rocket.android.util.extensions.serverLogoUrl
import
chat.rocket.android.util.extensions.termsOfServiceUrl
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.login
import
chat.rocket.core.internal.rest.me
import
chat.rocket.core.internal.rest.registerPushToken
import
chat.rocket.core.internal.rest.signup
import
chat.rocket.core.model.Myself
import
javax.inject.Inject
...
...
@@ -60,10 +62,10 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
try
{
// TODO This function returns a user so should we save it?
client
.
signup
(
email
,
name
,
username
,
password
)
retryIO
(
"signup"
)
{
client
.
signup
(
email
,
name
,
username
,
password
)
}
// TODO This function returns a user token so should we save it?
client
.
login
(
username
,
password
)
val
me
=
client
.
me
()
retryIO
(
"login"
)
{
client
.
login
(
username
,
password
)
}
val
me
=
retryIO
(
"me"
)
{
client
.
me
()
}
localRepository
.
save
(
LocalRepository
.
CURRENT_USERNAME_KEY
,
me
.
username
)
saveAccount
(
me
)
registerPushToken
()
...
...
@@ -88,13 +90,13 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
fun
termsOfService
()
{
serverInteractor
.
get
()
?.
let
{
navigator
.
toWebPage
(
UrlHelper
.
getTermsOfServiceUrl
(
it
))
navigator
.
toWebPage
(
it
.
termsOfServiceUrl
(
))
}
}
fun
privacyPolicy
()
{
serverInteractor
.
get
()
?.
let
{
navigator
.
toWebPage
(
UrlHelper
.
getPrivacyPolicyUrl
(
it
))
navigator
.
toWebPage
(
it
.
privacyPolicyUrl
(
))
}
}
...
...
@@ -108,12 +110,12 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
private
suspend
fun
saveAccount
(
me
:
Myself
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
currentServer
.
serverLogoUrl
(
it
)
}
val
logo
=
settings
.
wideTile
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
currentServer
.
serverLogoUrl
(
it
)
}
val
thumb
=
UrlHelper
.
getAvatarUrl
(
currentServer
,
me
.
username
!!
)
val
thumb
=
currentServer
.
avatarUrl
(
me
.
username
!!
)
val
account
=
Account
(
currentServer
,
icon
,
logo
,
me
.
username
!!
,
thumb
)
saveAccountInteractor
.
save
(
account
)
}
...
...
app/src/main/java/chat/rocket/android/authentication/twofactor/presentation/TwoFAPresenter.kt
View file @
4b95f252
...
...
@@ -3,13 +3,15 @@ package chat.rocket.android.authentication.twofactor.presentation
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.NetworkHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.extensions.registerPushToken
import
chat.rocket.android.util.extensions.serverLogoUrl
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatAuthException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.util.ifNull
...
...
@@ -50,9 +52,10 @@ class TwoFAPresenter @Inject constructor(private val view: TwoFAView,
view
.
showLoading
()
try
{
// The token is saved via the client TokenProvider
val
token
=
val
token
=
retryIO
(
"login"
)
{
client
.
login
(
usernameOrEmail
,
password
,
twoFactorAuthenticationCode
)
val
me
=
client
.
me
()
}
val
me
=
retryIO
(
"me"
)
{
client
.
me
()
}
saveAccount
(
me
)
tokenRepository
.
save
(
server
,
token
)
registerPushToken
()
...
...
@@ -90,12 +93,12 @@ class TwoFAPresenter @Inject constructor(private val view: TwoFAView,
private
suspend
fun
saveAccount
(
me
:
Myself
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
currentServer
.
serverLogoUrl
(
it
)
}
val
logo
=
settings
.
wideTile
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
currentServer
.
serverLogoUrl
(
it
)
}
val
thumb
=
UrlHelper
.
getAvatarUrl
(
currentServer
,
me
.
username
!!
)
val
thumb
=
currentServer
.
avatarUrl
(
me
.
username
!!
)
val
account
=
Account
(
currentServer
,
icon
,
logo
,
me
.
username
!!
,
thumb
)
saveAccountInteractor
.
save
(
account
)
}
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
4b95f252
This diff is collapsed.
Click to expand it.
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
4b95f252
...
...
@@ -37,6 +37,7 @@ import kotlinx.android.synthetic.main.message_composer.*
import
kotlinx.android.synthetic.main.message_list.*
import
java.util.concurrent.atomic.AtomicInteger
import
javax.inject.Inject
import
kotlin.math.absoluteValue
fun
newInstance
(
chatRoomId
:
String
,
chatRoomName
:
String
,
...
...
@@ -132,6 +133,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
override
fun
onDestroyView
()
{
recycler_view
.
removeOnScrollListener
(
endlessRecyclerViewScrollListener
)
recycler_view
.
removeOnScrollListener
(
onScrollListener
)
recycler_view
.
removeOnLayoutChangeListener
(
layoutChangeListener
)
presenter
.
unsubscribeMessages
(
chatRoomId
)
handler
.
removeCallbacksAndMessages
(
null
)
unsubscribeTextMessage
()
...
...
@@ -205,53 +210,16 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
recycler_view
.
layoutManager
=
linearLayoutManager
recycler_view
.
itemAnimator
=
DefaultItemAnimator
()
if
(
dataSet
.
size
>=
30
)
{
recycler_view
.
addOnScrollListener
(
object
:
EndlessRecyclerViewScrollListener
(
linearLayoutManager
)
{
endlessRecyclerViewScrollListener
=
object
:
EndlessRecyclerViewScrollListener
(
recycler_view
.
layoutManager
as
LinearLayoutManager
)
{
override
fun
onLoadMore
(
page
:
Int
,
totalItemsCount
:
Int
,
recyclerView
:
RecyclerView
?)
{
presenter
.
loadMessages
(
chatRoomId
,
chatRoomType
,
page
*
30L
)
}
})
}
recycler_view
.
addOnLayoutChangeListener
{
_
,
_
,
_
,
_
,
bottom
,
_
,
_
,
_
,
oldBottom
->
val
y
=
oldBottom
-
bottom
if
(
Math
.
abs
(
y
)
>
0
)
{
// if y is positive the keyboard is up else it's down
recycler_view
.
post
{
if
(
y
>
0
||
Math
.
abs
(
verticalScrollOffset
.
get
())
>=
Math
.
abs
(
y
))
{
recycler_view
.
scrollBy
(
0
,
y
)
}
else
{
recycler_view
.
scrollBy
(
0
,
verticalScrollOffset
.
get
())
}
}
}
recycler_view
.
addOnScrollListener
(
endlessRecyclerViewScrollListener
)
}
recycler_view
.
addOnScrollListener
(
object
:
RecyclerView
.
OnScrollListener
()
{
var
state
=
AtomicInteger
(
RecyclerView
.
SCROLL_STATE_IDLE
)
override
fun
onScrollStateChanged
(
recyclerView
:
RecyclerView
,
newState
:
Int
)
{
state
.
compareAndSet
(
RecyclerView
.
SCROLL_STATE_IDLE
,
newState
)
when
(
newState
)
{
RecyclerView
.
SCROLL_STATE_IDLE
->
{
if
(!
state
.
compareAndSet
(
RecyclerView
.
SCROLL_STATE_SETTLING
,
newState
))
{
state
.
compareAndSet
(
RecyclerView
.
SCROLL_STATE_DRAGGING
,
newState
)
}
}
RecyclerView
.
SCROLL_STATE_DRAGGING
->
{
state
.
compareAndSet
(
RecyclerView
.
SCROLL_STATE_IDLE
,
newState
)
}
RecyclerView
.
SCROLL_STATE_SETTLING
->
{
state
.
compareAndSet
(
RecyclerView
.
SCROLL_STATE_DRAGGING
,
newState
)
}
}
}
override
fun
onScrolled
(
recyclerView
:
RecyclerView
,
dx
:
Int
,
dy
:
Int
)
{
if
(
state
.
get
()
!=
RecyclerView
.
SCROLL_STATE_IDLE
)
{
verticalScrollOffset
.
getAndAdd
(
dy
)
}
}
})
recycler_view
.
addOnLayoutChangeListener
(
layoutChangeListener
)
recycler_view
.
addOnScrollListener
(
onScrollListener
)
}
val
oldMessagesCount
=
adapter
.
itemCount
...
...
@@ -264,6 +232,49 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
}
private
val
layoutChangeListener
=
View
.
OnLayoutChangeListener
{
_
,
_
,
_
,
_
,
bottom
,
_
,
_
,
_
,
oldBottom
->
val
y
=
oldBottom
-
bottom
if
(
y
.
absoluteValue
>
0
&&
isAdded
)
{
// if y is positive the keyboard is up else it's down
recycler_view
.
post
{
if
(
y
>
0
||
verticalScrollOffset
.
get
().
absoluteValue
>=
y
.
absoluteValue
)
{
recycler_view
.
scrollBy
(
0
,
y
)
}
else
{
recycler_view
.
scrollBy
(
0
,
verticalScrollOffset
.
get
())
}
}
}
}
private
lateinit
var
endlessRecyclerViewScrollListener
:
EndlessRecyclerViewScrollListener
private
val
onScrollListener
=
object
:
RecyclerView
.
OnScrollListener
()
{
var
state
=
AtomicInteger
(
RecyclerView
.
SCROLL_STATE_IDLE
)
override
fun
onScrollStateChanged
(
recyclerView
:
RecyclerView
,
newState
:
Int
)
{
state
.
compareAndSet
(
RecyclerView
.
SCROLL_STATE_IDLE
,
newState
)
when
(
newState
)
{
RecyclerView
.
SCROLL_STATE_IDLE
->
{
if
(!
state
.
compareAndSet
(
RecyclerView
.
SCROLL_STATE_SETTLING
,
newState
))
{
state
.
compareAndSet
(
RecyclerView
.
SCROLL_STATE_DRAGGING
,
newState
)
}
}
RecyclerView
.
SCROLL_STATE_DRAGGING
->
{
state
.
compareAndSet
(
RecyclerView
.
SCROLL_STATE_IDLE
,
newState
)
}
RecyclerView
.
SCROLL_STATE_SETTLING
->
{
state
.
compareAndSet
(
RecyclerView
.
SCROLL_STATE_DRAGGING
,
newState
)
}
}
}
override
fun
onScrolled
(
recyclerView
:
RecyclerView
,
dx
:
Int
,
dy
:
Int
)
{
if
(
state
.
get
()
!=
RecyclerView
.
SCROLL_STATE_IDLE
)
{
verticalScrollOffset
.
getAndAdd
(
dy
)
}
}
}
override
fun
sendMessage
(
text
:
String
)
{
if
(!
text
.
isBlank
())
{
if
(!
text
.
startsWith
(
"/"
))
{
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
View file @
4b95f252
...
...
@@ -9,9 +9,9 @@ import android.text.style.ForegroundColorSpan
import
android.text.style.StyleSpan
import
chat.rocket.android.R
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.widget.emoji.EmojiParser
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.MessageType
...
...
@@ -235,7 +235,7 @@ class ViewModelMapper @Inject constructor(private val context: Context,
val
username
=
message
.
sender
?.
username
?:
"?"
return
baseUrl
?.
let
{
UrlHelper
.
getAvatarUrl
(
baseUrl
,
username
)
baseUrl
.
avatarUrl
(
username
)
}
}
...
...
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
4b95f252
...
...
@@ -12,6 +12,7 @@ import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.chatRooms
import
chat.rocket.android.server.infraestructure.state
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.BaseRoom
import
chat.rocket.common.model.RoomType
...
...
@@ -94,7 +95,9 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
try
{
val
roomList
=
getChatRoomsInteractor
.
getByName
(
currentServer
,
name
)
if
(
roomList
.
isEmpty
())
{
val
(
users
,
rooms
)
=
client
.
spotlight
(
name
)
val
(
users
,
rooms
)
=
retryIO
(
"spotlight($name)"
)
{
client
.
spotlight
(
name
)
}
val
chatRoomsCombined
=
mutableListOf
<
ChatRoom
>()
chatRoomsCombined
.
addAll
(
usersToChatRooms
(
users
))
chatRoomsCombined
.
addAll
(
roomsToChatRooms
(
rooms
))
...
...
@@ -161,7 +164,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
private
suspend
fun
loadRooms
():
List
<
ChatRoom
>
{
val
chatRooms
=
manager
.
chatRooms
().
update
val
chatRooms
=
retryIO
(
"chatRooms"
)
{
manager
.
chatRooms
().
update
}
val
sortedRooms
=
sortRooms
(
chatRooms
)
Timber
.
d
(
"Loaded rooms: ${sortedRooms.size}"
)
saveChatRoomsInteractor
.
save
(
currentServer
,
sortedRooms
)
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsAdapter.kt
View file @
4b95f252
...
...
@@ -12,11 +12,11 @@ import android.view.View
import
android.view.ViewGroup
import
android.widget.TextView
import
chat.rocket.android.R
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.checkIfMyself
import
chat.rocket.android.server.domain.PublicSettings
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.content
import
chat.rocket.android.util.extensions.inflate
import
chat.rocket.android.util.extensions.setVisible
...
...
@@ -75,7 +75,7 @@ class ChatRoomsAdapter(private val context: Context,
private
fun
bindAvatar
(
chatRoom
:
ChatRoom
,
drawee
:
SimpleDraweeView
)
{
val
avatarId
=
if
(
chatRoom
.
type
is
RoomType
.
DirectMessage
)
chatRoom
.
name
else
"@${chatRoom.name}"
drawee
.
setImageURI
(
UrlHelper
.
getAvatarUrl
(
chatRoom
.
client
.
url
,
avatarId
))
drawee
.
setImageURI
(
chatRoom
.
client
.
url
.
avatarUrl
(
avatarId
))
}
private
fun
bindName
(
chatRoom
:
ChatRoom
,
textView
:
TextView
)
{
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
4b95f252
...
...
@@ -158,15 +158,16 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
listJob
?.
cancel
()
listJob
=
launch
(
UI
)
{
val
adapter
=
recycler_view
.
adapter
as
SimpleSectionedRecyclerViewAdapter
// FIXME https://fabric.io/rocketchat3/android/apps/chat.rocket.android
.dev/issues/5a90d4718cb3c2fa63b3f557?time=last-seven-days
// TODO - fix this bug to reenable DiffUtil
val
diff
=
async
(
CommonPool
)
{
// FIXME https://fabric.io/rocketchat3/android/apps/chat.rocket.android
/issues/5ac2916c36c7b235275ccccf
// TODO - fix this bug to re
-
enable DiffUtil
/*
val diff = async(CommonPool) {
DiffUtil.calculateDiff(RoomsDiffCallback(adapter.baseAdapter.dataSet, newDataSet))
}.
await
()
}.await()
*/
if
(
isActive
)
{
adapter
.
baseAdapter
.
updateRooms
(
newDataSet
)
diff
.
dispatchUpdatesTo
(
adapter
)
// TODO - fix crash to re-enable diff.dispatchUpdatesTo(adapter)
adapter
.
notifyDataSetChanged
()
//Set sections always after data set is updated
setSections
()
...
...
app/src/main/java/chat/rocket/android/helper/OauthHelper.kt
View file @
4b95f252
package
chat.rocket.android.helper
import
chat.rocket.android.util.extensions.removeTrailingSlash
object
OauthHelper
{
/**
...
...
@@ -27,7 +29,7 @@ object OauthHelper {
fun
getGoogleOauthUrl
(
clientId
:
String
,
serverUrl
:
String
,
state
:
String
):
String
{
return
"https://accounts.google.com/o/oauth2/v2/auth"
+
"?client_id=$clientId"
+
"&redirect_uri=${
UrlHelper.removeTrailingSlash(serverUrl
)}/_oauth/google?close"
+
"&redirect_uri=${
serverUrl.removeTrailingSlash(
)}/_oauth/google?close"
+
"&state=$state"
+
"&response_type=code"
+
"&scope=email%20profile"
...
...
@@ -44,7 +46,7 @@ object OauthHelper {
fun
getLinkedinOauthUrl
(
clientId
:
String
,
serverUrl
:
String
,
state
:
String
):
String
{
return
"https://linkedin.com/oauth/v2/authorization"
+
"?client_id=$clientId"
+
"&redirect_uri=${
UrlHelper.removeTrailingSlash(serverUrl
)}/_oauth/linkedin?close"
+
"&redirect_uri=${
serverUrl.removeTrailingSlash(
)}/_oauth/linkedin?close"
+
"&state=$state"
+
"&response_type=code"
}
...
...
@@ -60,7 +62,7 @@ object OauthHelper {
fun
getGitlabOauthUrl
(
clientId
:
String
,
serverUrl
:
String
,
state
:
String
):
String
{
return
"https://gitlab.com/oauth/authorize"
+
"?client_id=$clientId"
+
"&redirect_uri=${
UrlHelper.removeTrailingSlash(serverUrl
)}/_oauth/gitlab?close"
+
"&redirect_uri=${
serverUrl.removeTrailingSlash(
)}/_oauth/gitlab?close"
+
"&state=$state"
+
"&response_type=code"
+
"&scope=read_user"
...
...
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
deleted
100644 → 0
View file @
6f0cc896
package
chat.rocket.android.helper
import
android.util.Patterns
object
UrlHelper
{
/**
* Returns the avatar URL.
*
* @param serverUrl The server URL.
* @param avatarName The avatar name.
* @return The avatar URL.
*/
fun
getAvatarUrl
(
serverUrl
:
String
,
avatarName
:
String
,
format
:
String
=
"jpeg"
):
String
=
removeTrailingSlash
(
serverUrl
)
+
"/avatar/"
+
removeTrailingSlash
(
avatarName
)
+
"?format=$format"
/**
* Returns the server logo URL.
*
* @param serverUrl The server URL.
* @param favicon The faviconLarge from the server settings.
* @return The server logo URL.
*/
fun
getServerLogoUrl
(
serverUrl
:
String
,
favicon
:
String
):
String
=
removeTrailingSlash
(
serverUrl
)
+
"/$favicon"
/**
* Returns the CAS URL.
*
* @param casLoginUrl The CAS login URL from the server settings.
* @param serverUrl The server URL.
* @param token The token to be send to the CAS server.
* @return The avatar URL.
*/
fun
getCasUrl
(
casLoginUrl
:
String
,
serverUrl
:
String
,
token
:
String
):
String
=
removeTrailingSlash
(
casLoginUrl
)
+
"?service="
+
removeTrailingSlash
(
serverUrl
)
+
"/_cas/"
+
token
/**
* Returns the server's Terms of Service URL.
*
* @param serverUrl The server URL.
* @return The server's Terms of Service URL.
*/
fun
getTermsOfServiceUrl
(
serverUrl
:
String
)
=
removeTrailingSlash
(
serverUrl
)
+
"/terms-of-service"
/**
* Returns the server's Privacy Policy URL.
*
* @param serverUrl The server URL.
* @return The server's Privacy Policy URL.
*/
fun
getPrivacyPolicyUrl
(
serverUrl
:
String
)
=
removeTrailingSlash
(
serverUrl
)
+
"/privacy-policy"
/**
* Returns an URL without trailing slash.
*
* @param serverUrl The URL to remove the trailing slash (if exists).
* @return An URL without trailing slash.
*/
fun
removeTrailingSlash
(
serverUrl
:
String
):
String
{
return
if
(
serverUrl
[
serverUrl
.
length
-
1
]
==
'/'
)
{
serverUrl
.
replace
(
"/+$"
,
""
)
}
else
{
serverUrl
}
}
/**
* Checks if the given URL is valid or not.
* @param url The url to check its valid.
* @return True if url is valid, false otherwise.
*/
fun
isValidUrl
(
url
:
String
):
Boolean
=
Patterns
.
WEB_URL
.
matcher
(
url
).
matches
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt
View file @
4b95f252
package
chat.rocket.android.main.presentation
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.main.viewmodel.NavHeaderViewModel
import
chat.rocket.android.main.viewmodel.NavHeaderViewModelMapper
...
...
@@ -12,6 +11,8 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.presentation.CheckServerPresenter
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.extensions.registerPushToken
import
chat.rocket.android.util.extensions.serverLogoUrl
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatAuthException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.util.ifNull
...
...
@@ -54,7 +55,7 @@ class MainPresenter @Inject constructor(
checkServerInfo
()
launchUI
(
strategy
)
{
try
{
val
me
=
client
.
me
()
val
me
=
retryIO
(
"me"
)
{
client
.
me
()
}
val
model
=
navHeaderMapper
.
mapToViewModel
(
me
)
saveAccount
(
model
)
...
...
@@ -79,7 +80,7 @@ class MainPresenter @Inject constructor(
private
suspend
fun
saveAccount
(
me
:
NavHeaderViewModel
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
currentServer
.
serverLogoUrl
(
it
)
}
val
account
=
Account
(
currentServer
,
icon
,
me
.
serverLogo
,
me
.
username
,
me
.
avatar
)
saveAccountInteractor
.
save
(
account
)
...
...
@@ -92,7 +93,7 @@ class MainPresenter @Inject constructor(
launchUI
(
strategy
)
{
try
{
clearTokens
()
client
.
logout
()
retryIO
(
"logout"
)
{
client
.
logout
()
}
}
catch
(
exception
:
RocketChatException
)
{
Timber
.
d
(
exception
,
"Error calling logout"
)
exception
.
message
?.
let
{
...
...
@@ -119,7 +120,11 @@ class MainPresenter @Inject constructor(
serverInteractor
.
clear
()
val
pushToken
=
localRepository
.
get
(
LocalRepository
.
KEY_PUSH_TOKEN
)
if
(
pushToken
!=
null
)
{
client
.
unregisterPushToken
(
pushToken
)
try
{
retryIO
(
"unregisterPushToken"
)
{
client
.
unregisterPushToken
(
pushToken
)
}
}
catch
(
ex
:
Exception
)
{
Timber
.
d
(
ex
,
"Error unregistering push token"
)
}
}
localRepository
.
clearAllFromServer
(
currentServer
)
}
...
...
app/src/main/java/chat/rocket/android/main/viewmodel/NavHeaderViewModelMapper.kt
View file @
4b95f252
package
chat.rocket.android.main.viewmodel
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.serverLogoUrl
import
chat.rocket.core.model.Myself
import
javax.inject.Inject
...
...
@@ -12,9 +13,9 @@ class NavHeaderViewModelMapper @Inject constructor(serverInteractor: GetCurrentS
fun
mapToViewModel
(
me
:
Myself
):
NavHeaderViewModel
{
val
username
=
mapUsername
(
me
)
val
thumb
=
me
.
username
?.
let
{
UrlHelper
.
getAvatarUrl
(
currentServer
,
it
)
}
val
thumb
=
me
.
username
?.
let
{
currentServer
.
avatarUrl
(
it
)
}
val
image
=
settings
.
wideTile
()
?:
settings
.
faviconLarge
()
val
logo
=
image
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
logo
=
image
?.
let
{
currentServer
.
serverLogoUrl
(
it
)
}
return
NavHeaderViewModel
(
username
,
currentServer
,
thumb
,
logo
)
}
...
...
app/src/main/java/chat/rocket/android/members/presentation/MembersPresenter.kt
View file @
4b95f252
...
...
@@ -6,6 +6,7 @@ import chat.rocket.android.members.viewmodel.MemberViewModelMapper
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
...
...
@@ -26,7 +27,9 @@ class MembersPresenter @Inject constructor(private val view: MembersView,
try
{
view
.
showLoading
()
val
members
=
client
.
getMembers
(
chatRoomId
,
roomTypeOf
(
chatRoomType
),
offset
,
60
)
val
members
=
retryIO
(
"getMembers($chatRoomId, $chatRoomType, $offset)"
)
{
client
.
getMembers
(
chatRoomId
,
roomTypeOf
(
chatRoomType
),
offset
,
60
)
}
val
memberViewModels
=
mapper
.
mapToViewModelList
(
members
.
result
)
view
.
showMembers
(
memberViewModels
,
members
.
total
)
}
catch
(
ex
:
RocketChatException
)
{
...
...
app/src/main/java/chat/rocket/android/members/viewmodel/MemberViewModel.kt
View file @
4b95f252
package
chat.rocket.android.members.viewmodel
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.common.model.User
import
chat.rocket.core.model.Value
...
...
@@ -25,7 +25,7 @@ class MemberViewModel(private val member: User, private val settings: Map<String
private
fun
getUserAvatar
():
String
?
{
val
username
=
member
.
username
?:
"?"
return
baseUrl
?.
let
{
UrlHelper
.
getAvatarUrl
(
baseUrl
,
username
,
"png"
)
baseUrl
.
avatarUrl
(
username
,
"png"
)
}
}
...
...
app/src/main/java/chat/rocket/android/profile/presentation/ProfilePresenter.kt
View file @
4b95f252
package
chat.rocket.android.profile.presentation
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
...
...
@@ -25,9 +26,9 @@ class ProfilePresenter @Inject constructor(private val view: ProfileView,
launchUI
(
strategy
)
{
view
.
showLoading
()
try
{
val
myself
=
client
.
me
()
val
myself
=
retryIO
(
"me"
)
{
client
.
me
()
}
myselfId
=
myself
.
id
val
avatarUrl
=
UrlHelper
.
getAvatarUrl
(
serverUrl
,
myself
.
username
!!
)
val
avatarUrl
=
serverUrl
.
avatarUrl
(
myself
.
username
!!
)
view
.
showProfile
(
avatarUrl
,
myself
.
name
?:
""
,
...
...
@@ -51,9 +52,9 @@ class ProfilePresenter @Inject constructor(private val view: ProfileView,
view
.
showLoading
()
try
{
if
(
avatarUrl
!=
""
)
{
client
.
setAvatar
(
avatarUrl
)
retryIO
{
client
.
setAvatar
(
avatarUrl
)
}
}
val
user
=
client
.
updateProfile
(
myselfId
,
email
,
name
,
username
)
val
user
=
retryIO
{
client
.
updateProfile
(
myselfId
,
email
,
name
,
username
)
}
view
.
showProfileUpdateSuccessfullyMessage
()
loadUserProfile
()
}
catch
(
exception
:
RocketChatException
)
{
...
...
app/src/main/java/chat/rocket/android/push/FirebaseTokenService.kt
View file @
4b95f252
...
...
@@ -5,7 +5,6 @@ import chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.common.RocketChatException
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.registerPushToken
import
com.google.android.gms.gcm.GoogleCloudMessaging
import
com.google.android.gms.iid.InstanceID
...
...
app/src/main/java/chat/rocket/android/server/presentation/CheckServerPresenter.kt
View file @
4b95f252
...
...
@@ -5,6 +5,7 @@ import chat.rocket.android.authentication.server.presentation.VersionCheckView
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.util.VersionInfo
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.retryIO
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.serverInfo
import
timber.log.Timber
...
...
@@ -14,21 +15,25 @@ abstract class CheckServerPresenter constructor(private val strategy: CancelStra
private
val
view
:
VersionCheckView
)
{
internal
fun
checkServerInfo
()
{
launchUI
(
strategy
)
{
val
serverInfo
=
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)"
)
try
{
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)"
)
}
else
{
view
.
alertNotRecommendedVersion
()
}
}
else
{
view
.
alertNotRecommendedVersion
()
}
}
else
{
if
(!
isRecommendedVersion
)
{
view
.
blockAndAlertNotRequiredVersion
()
Timber
.
i
(
"Oops. Looks like your server is out-of-date! Minimum server version required ${BuildConfig.REQUIRED_SERVER_VERSION}!"
)
if
(!
isRecommendedVersion
)
{
view
.
blockAndAlertNotRequiredVersion
()
Timber
.
i
(
"Oops. Looks like your server is out-of-date! Minimum server version required ${BuildConfig.REQUIRED_SERVER_VERSION}!"
)
}
}
}
catch
(
ex
:
Exception
)
{
Timber
.
d
(
ex
,
"Error getting server info"
)
}
}
}
...
...
app/src/main/java/chat/rocket/android/settings/password/presentation/PasswordPresenter.kt
View file @
4b95f252
...
...
@@ -4,6 +4,7 @@ import chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.me
...
...
@@ -22,7 +23,10 @@ class PasswordPresenter @Inject constructor (private val view: PasswordView,
try
{
view
.
showLoading
()
client
.
updateProfile
(
client
.
me
().
id
,
null
,
null
,
password
,
null
)
val
me
=
retryIO
(
"me"
)
{
client
.
me
()
}
retryIO
(
"updateProfile(${me.id})"
)
{
client
.
updateProfile
(
me
.
id
,
null
,
null
,
password
,
null
)
}
view
.
showPasswordSuccessfullyUpdatedMessage
()
view
.
hideLoading
()
...
...
app/src/main/java/chat/rocket/android/util/IO.kt
0 → 100644
View file @
4b95f252
package
chat.rocket.android.util
import
chat.rocket.common.RocketChatNetworkErrorException
import
kotlinx.coroutines.experimental.delay
import
timber.log.Timber
const
val
DEFAULT_RETRY
=
3
suspend
fun
<
T
>
retryIO
(
description
:
String
=
"<missing description>"
,
times
:
Int
=
DEFAULT_RETRY
,
initialDelay
:
Long
=
100
,
// 0.1 second
maxDelay
:
Long
=
1000
,
// 1 second
factor
:
Double
=
2.0
,
block
:
suspend
()
->
T
):
T
{
var
currentDelay
=
initialDelay
repeat
(
times
-
1
)
{
currentTry
->
try
{
return
block
()
}
catch
(
e
:
RocketChatNetworkErrorException
)
{
Timber
.
d
(
e
,
"failed call($currentTry): $description"
)
e
.
printStackTrace
()
}
delay
(
currentDelay
)
currentDelay
=
(
currentDelay
*
factor
).
toLong
().
coerceAtMost
(
maxDelay
)
}
return
block
()
// last attempt
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/RocketChatClient.kt
View file @
4b95f252
...
...
@@ -2,6 +2,7 @@ package chat.rocket.android.util.extensions
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.retryIO
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.registerPushToken
import
kotlinx.coroutines.experimental.CommonPool
...
...
@@ -16,7 +17,9 @@ suspend fun RocketChatClient.registerPushToken(
launch
(
CommonPool
)
{
accounts
.
forEach
{
account
->
try
{
factory
.
create
(
account
.
serverUrl
).
registerPushToken
(
token
)
retryIO
(
description
=
"register push token: ${account.serverUrl}"
)
{
factory
.
create
(
account
.
serverUrl
).
registerPushToken
(
token
)
}
}
catch
(
ex
:
Exception
)
{
Timber
.
d
(
ex
,
"Error registering Push token for ${account.serverUrl}"
)
ex
.
printStackTrace
()
...
...
app/src/main/java/chat/rocket/android/util/extensions/String.kt
0 → 100644
View file @
4b95f252
package
chat.rocket.android.util.extensions
import
android.util.Patterns
fun
String
.
removeTrailingSlash
():
String
{
return
if
(
isNotEmpty
()
&&
this
[
length
-
1
]
==
'/'
)
{
this
.
replace
(
"/+$"
,
""
)
}
else
{
this
}
}
fun
String
.
avatarUrl
(
avatar
:
String
,
format
:
String
=
"jpeg"
)
=
"${removeTrailingSlash()}/avatar/${avatar.removeTrailingSlash()}?format=$format"
fun
String
.
serverLogoUrl
(
favicon
:
String
)
=
"${removeTrailingSlash()}/$favicon"
fun
String
.
casUrl
(
serverUrl
:
String
,
token
:
String
)
=
"${removeTrailingSlash()}?service=${serverUrl.removeTrailingSlash()}/_cas/$token"
fun
String
.
termsOfServiceUrl
()
=
"${removeTrailingSlash()}/terms-of-service"
fun
String
.
privacyPolicyUrl
()
=
"${removeTrailingSlash()}/privacy-policy"
fun
String
.
isValidUrl
():
Boolean
=
Patterns
.
WEB_URL
.
matcher
(
this
).
matches
()
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Uri.kt
View file @
4b95f252
...
...
@@ -29,14 +29,14 @@ fun Uri.getFileName(context: Context): String? {
fun
Uri
.
getFileSize
(
context
:
Context
):
Int
{
val
cursor
=
context
.
contentResolver
.
query
(
this
,
null
,
null
,
null
,
null
,
null
)
var
fileSize
:
String
?
=
null
cursor
.
use
{
cursor
->
val
fileSize
=
cursor
?.
use
{
val
sizeIndex
=
cursor
.
getColumnIndex
(
OpenableColumns
.
SIZE
)
if
(
cursor
!=
null
&&
cursor
.
moveToFirst
())
{
if
(
cursor
.
moveToFirst
())
{
if
(!
cursor
.
isNull
(
sizeIndex
))
{
fileSize
=
cursor
.
getString
(
sizeIndex
)
return
@use
cursor
.
getString
(
sizeIndex
)
}
}
return
@use
null
}
return
fileSize
?.
toIntOrNull
()
?:
-
1
}
...
...
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