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
0d5bbd04
Commit
0d5bbd04
authored
Mar 21, 2018
by
Lucio Maciel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial multi server support...
parent
2e7a0037
Changes
57
Hide whitespace changes
Inline
Side-by-side
Showing
57 changed files
with
920 additions
and
81 deletions
+920
-81
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+4
-0
AuthenticationModule.kt
.../rocket/android/authentication/di/AuthenticationModule.kt
+1
-2
LoginPresenter.kt
...droid/authentication/login/presentation/LoginPresenter.kt
+25
-3
AuthenticationNavigator.kt
...id/authentication/presentation/AuthenticationNavigator.kt
+2
-3
AuthenticationPresenter.kt
...id/authentication/presentation/AuthenticationPresenter.kt
+4
-2
ServerFragment.kt
...rocket/android/authentication/server/ui/ServerFragment.kt
+12
-4
SignupPresenter.kt
...oid/authentication/signup/presentation/SignupPresenter.kt
+23
-3
SignupFragment.kt
...rocket/android/authentication/signup/ui/SignupFragment.kt
+6
-2
TwoFAPresenter.kt
...d/authentication/twofactor/presentation/TwoFAPresenter.kt
+25
-4
TwoFAFragment.kt
...cket/android/authentication/twofactor/ui/TwoFAFragment.kt
+9
-3
AuthenticationActivity.kt
...ocket/android/authentication/ui/AuthenticationActivity.kt
+14
-1
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+9
-3
PinnedMessagesFragment.kt
...chat/rocket/android/chatroom/ui/PinnedMessagesFragment.kt
+6
-2
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+1
-1
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+6
-2
ActivityBuilder.kt
...java/chat/rocket/android/dagger/module/ActivityBuilder.kt
+6
-0
AppModule.kt
.../main/java/chat/rocket/android/dagger/module/AppModule.kt
+5
-0
UrlHelper.kt
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
+10
-0
AccountViewHolder.kt
...ava/chat/rocket/android/main/adapter/AccountViewHolder.kt
+16
-0
AccountsAdapter.kt
.../java/chat/rocket/android/main/adapter/AccountsAdapter.kt
+54
-0
AddAccountViewHolder.kt
.../chat/rocket/android/main/adapter/AddAccountViewHolder.kt
+6
-0
MainModule.kt
app/src/main/java/chat/rocket/android/main/di/MainModule.kt
+1
-1
MainNavigator.kt
...va/chat/rocket/android/main/presentation/MainNavigator.kt
+13
-2
MainPresenter.kt
...va/chat/rocket/android/main/presentation/MainPresenter.kt
+56
-5
MainView.kt
...in/java/chat/rocket/android/main/presentation/MainView.kt
+4
-5
MainActivity.kt
...src/main/java/chat/rocket/android/main/ui/MainActivity.kt
+51
-5
NavHeaderViewModel.kt
.../chat/rocket/android/main/viewmodel/NavHeaderViewModel.kt
+8
-0
NavHeaderViewModelMapper.kt
...rocket/android/main/viewmodel/NavHeaderViewModelMapper.kt
+28
-0
MembersFragment.kt
...in/java/chat/rocket/android/members/ui/MembersFragment.kt
+6
-2
ProfileFragment.kt
...in/java/chat/rocket/android/profile/ui/ProfileFragment.kt
+9
-3
ChangeServerModule.kt
.../java/chat/rocket/android/server/di/ChangeServerModule.kt
+30
-0
AccountsRepository.kt
...a/chat/rocket/android/server/domain/AccountsRepository.kt
+9
-0
GetAccountsInteractor.kt
...hat/rocket/android/server/domain/GetAccountsInteractor.kt
+7
-0
RefreshSettingsInteractor.kt
...rocket/android/server/domain/RefreshSettingsInteractor.kt
+3
-2
RemoveAccountInterector.kt
...t/rocket/android/server/domain/RemoveAccountInterector.kt
+9
-0
SaveAccountInteractor.kt
...hat/rocket/android/server/domain/SaveAccountInteractor.kt
+8
-0
SaveServerInteractor.java
...at/rocket/android/server/domain/SaveServerInteractor.java
+0
-4
SettingsRepository.kt
...a/chat/rocket/android/server/domain/SettingsRepository.kt
+5
-0
Account.kt
...n/java/chat/rocket/android/server/domain/model/Account.kt
+12
-0
ConnectionManagerFactory.kt
...ndroid/server/infraestructure/ConnectionManagerFactory.kt
+2
-0
SharedPreferencesAccountsRepository.kt
...er/infraestructure/SharedPreferencesAccountsRepository.kt
+55
-0
ChangeServerNavigator.kt
...cket/android/server/presentation/ChangeServerNavigator.kt
+19
-0
ChangeServerPresenter.kt
...cket/android/server/presentation/ChangeServerPresenter.kt
+60
-0
ChangeServerView.kt
...at/rocket/android/server/presentation/ChangeServerView.kt
+7
-0
ChangeServerActivity.kt
...ava/chat/rocket/android/server/ui/ChangeServerActivity.kt
+51
-0
Animation.kt
...ain/java/chat/rocket/android/util/extensions/Animation.kt
+2
-2
Ui.kt
app/src/main/java/chat/rocket/android/util/extensions/Ui.kt
+14
-7
black_gradient.xml
app/src/main/res/drawable/black_gradient.xml
+12
-0
ic_add_24dp.xml
app/src/main/res/drawable/ic_add_24dp.xml
+2
-4
ic_expand_more_24dp.xml
app/src/main/res/drawable/ic_expand_more_24dp.xml
+9
-0
activity_main.xml
app/src/main/res/layout/activity_main.xml
+19
-4
item_account.xml
app/src/main/res/layout/item_account.xml
+45
-0
item_add_account.xml
app/src/main/res/layout/item_add_account.xml
+34
-0
nav_header.xml
app/src/main/res/layout/nav_header.xml
+82
-0
colors.xml
app/src/main/res/values/colors.xml
+2
-0
dimens.xml
app/src/main/res/values/dimens.xml
+1
-0
strings.xml
app/src/main/res/values/strings.xml
+1
-0
No files found.
app/src/main/AndroidManifest.xml
View file @
0d5bbd04
...
...
@@ -35,6 +35,10 @@
</intent-filter>
</activity>
<activity
android:name=
".server.ui.ChangeServerActivity"
android:theme=
"@style/AuthenticationTheme"
/>
<activity
android:name=
".main.ui.MainActivity"
android:windowSoftInputMode=
"adjustResize|stateAlwaysHidden"
...
...
app/src/main/java/chat/rocket/android/authentication/di/AuthenticationModule.kt
View file @
0d5bbd04
package
chat.rocket.android.authentication.di
import
android.content.Context
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.authentication.ui.AuthenticationActivity
import
chat.rocket.android.dagger.scope.PerActivity
...
...
@@ -12,5 +11,5 @@ class AuthenticationModule {
@Provides
@PerActivity
fun
provideAuthenticationNavigator
(
activity
:
AuthenticationActivity
,
context
:
Context
)
=
AuthenticationNavigator
(
activity
,
context
)
fun
provideAuthenticationNavigator
(
activity
:
AuthenticationActivity
)
=
AuthenticationNavigator
(
activity
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/login/presentation/LoginPresenter.kt
View file @
0d5bbd04
...
...
@@ -6,7 +6,9 @@ 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.generateRandomString
import
chat.rocket.android.util.extensions.isEmailValid
...
...
@@ -16,6 +18,7 @@ import chat.rocket.common.RocketChatTwoFactorException
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
java.util.concurrent.TimeUnit
import
javax.inject.Inject
...
...
@@ -27,9 +30,12 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
private
val
localRepository
:
LocalRepository
,
private
val
settingsInteractor
:
GetSettingsInteractor
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
saveAccountInteractor
:
SaveAccountInteractor
,
factory
:
RocketChatClientFactory
)
{
// TODO - we should validate the current server when opening the app, and have a nonnull get()
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
private
var
settings
:
PublicSettings
=
settingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
fun
setupView
()
{
val
server
=
serverInteractor
.
get
()
...
...
@@ -125,7 +131,9 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
}
}
saveToken
(
server
,
TokenModel
(
token
.
userId
,
token
.
authToken
),
client
.
me
().
username
)
val
me
=
client
.
me
()
saveToken
(
server
,
TokenModel
(
token
.
userId
,
token
.
authToken
),
me
.
username
)
saveAccount
(
me
)
registerPushToken
()
navigator
.
toChatList
()
}
catch
(
exception
:
RocketChatException
)
{
...
...
@@ -163,7 +171,9 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
if
(
server
!=
null
)
{
delay
(
3
,
TimeUnit
.
SECONDS
)
val
token
=
client
.
loginWithCas
(
casToken
)
saveToken
(
server
,
TokenModel
(
token
.
userId
,
token
.
authToken
),
client
.
me
().
username
)
val
me
=
client
.
me
()
saveToken
(
server
,
TokenModel
(
token
.
userId
,
token
.
authToken
),
me
.
username
)
saveAccount
(
me
)
registerPushToken
()
navigator
.
toChatList
()
}
else
{
...
...
@@ -199,4 +209,16 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
}
// TODO: Schedule push token registering when it comes up null
}
private
suspend
fun
saveAccount
(
me
:
Myself
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
logo
=
settings
.
wideTile
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
thumb
=
UrlHelper
.
getAvatarUrl
(
currentServer
,
me
.
username
!!
)
val
account
=
Account
(
currentServer
,
icon
,
logo
,
me
.
username
!!
,
thumb
)
saveAccountInteractor
.
save
(
account
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/presentation/AuthenticationNavigator.kt
View file @
0d5bbd04
package
chat.rocket.android.authentication.presentation
import
android.content.Context
import
android.content.Intent
import
chat.rocket.android.R
import
chat.rocket.android.authentication.login.ui.LoginFragment
...
...
@@ -11,7 +10,7 @@ import chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.util.extensions.addFragmentBackStack
import
chat.rocket.android.webview.ui.webViewIntent
class
AuthenticationNavigator
(
internal
val
activity
:
AuthenticationActivity
,
internal
val
context
:
Context
)
{
class
AuthenticationNavigator
(
internal
val
activity
:
AuthenticationActivity
)
{
fun
toLogin
()
{
activity
.
addFragmentBackStack
(
"LoginFragment"
,
R
.
id
.
fragment_container
)
{
...
...
@@ -32,7 +31,7 @@ class AuthenticationNavigator(internal val activity: AuthenticationActivity, int
}
fun
toWebPage
(
url
:
String
)
{
activity
.
startActivity
(
context
.
webViewIntent
(
url
))
activity
.
startActivity
(
activity
.
webViewIntent
(
url
))
activity
.
overridePendingTransition
(
R
.
anim
.
slide_up
,
R
.
anim
.
hold
)
}
...
...
app/src/main/java/chat/rocket/android/authentication/presentation/AuthenticationPresenter.kt
View file @
0d5bbd04
...
...
@@ -3,6 +3,8 @@ package chat.rocket.android.authentication.presentation
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.MultiServerTokenRepository
import
chat.rocket.android.server.domain.SettingsRepository
import
chat.rocket.android.server.infraestructure.ConnectionManager
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.common.model.Token
import
chat.rocket.core.TokenRepository
import
javax.inject.Inject
...
...
@@ -13,12 +15,12 @@ class AuthenticationPresenter @Inject constructor(private val navigator: Authent
private
val
settingsRepository
:
SettingsRepository
,
private
val
tokenRepository
:
TokenRepository
)
{
fun
loadCredentials
(
callback
:
(
authenticated
:
Boolean
)
->
Unit
)
{
fun
loadCredentials
(
newServer
:
Boolean
,
callback
:
(
authenticated
:
Boolean
)
->
Unit
)
{
val
currentServer
=
getCurrentServerInteractor
.
get
()
val
serverToken
=
currentServer
?.
let
{
multiServerRepository
.
get
(
currentServer
)
}
val
settings
=
currentServer
?.
let
{
settingsRepository
.
get
(
currentServer
)
}
if
(
currentServer
==
null
||
serverToken
==
null
||
settings
==
null
)
{
if
(
newServer
||
currentServer
==
null
||
serverToken
==
null
||
settings
==
null
)
{
callback
(
false
)
}
else
{
tokenRepository
.
save
(
Token
(
serverToken
.
userId
,
serverToken
.
authToken
))
...
...
app/src/main/java/chat/rocket/android/authentication/server/ui/ServerFragment.kt
View file @
0d5bbd04
...
...
@@ -56,13 +56,21 @@ class ServerFragment : Fragment(), ServerView {
enableUserInput
(
true
)
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
){
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
override
fun
showGenericErrorMessage
()
{
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
}
override
fun
showNoInternetConnection
()
=
showMessage
(
getString
(
R
.
string
.
msg_no_internet_connection
))
override
fun
showNoInternetConnection
()
{
showMessage
(
getString
(
R
.
string
.
msg_no_internet_connection
))
}
private
fun
enableUserInput
(
value
:
Boolean
)
{
button_connect
.
isEnabled
=
value
...
...
app/src/main/java/chat/rocket/android/authentication/signup/presentation/SignupPresenter.kt
View file @
0d5bbd04
...
...
@@ -5,7 +5,9 @@ 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.GetCurrentServerInteractor
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.launchUI
import
chat.rocket.common.RocketChatException
...
...
@@ -15,6 +17,7 @@ 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
class
SignupPresenter
@Inject
constructor
(
private
val
view
:
SignupView
,
...
...
@@ -22,8 +25,12 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
private
val
navigator
:
AuthenticationNavigator
,
private
val
localRepository
:
LocalRepository
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
factory
:
RocketChatClientFactory
)
{
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
factory
:
RocketChatClientFactory
,
private
val
saveAccountInteractor
:
SaveAccountInteractor
,
settingsInteractor
:
GetSettingsInteractor
)
{
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
private
var
settings
:
PublicSettings
=
settingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
fun
signup
(
name
:
String
,
username
:
String
,
password
:
String
,
email
:
String
)
{
val
server
=
serverInteractor
.
get
()
...
...
@@ -56,6 +63,7 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
client
.
login
(
username
,
password
)
val
me
=
client
.
me
()
localRepository
.
save
(
LocalRepository
.
USERNAME_KEY
,
me
.
username
)
saveAccount
(
me
)
registerPushToken
()
navigator
.
toChatList
()
}
catch
(
exception
:
RocketChatException
)
{
...
...
@@ -94,4 +102,16 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
}
// TODO: Schedule push token registering when it comes up null
}
private
suspend
fun
saveAccount
(
me
:
Myself
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
logo
=
settings
.
wideTile
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
thumb
=
UrlHelper
.
getAvatarUrl
(
currentServer
,
me
.
username
!!
)
val
account
=
Account
(
currentServer
,
icon
,
logo
,
me
.
username
!!
,
thumb
)
saveAccountInteractor
.
save
(
account
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/signup/ui/SignupFragment.kt
View file @
0d5bbd04
...
...
@@ -97,9 +97,13 @@ class SignupFragment : Fragment(), SignupView {
enableUserInput
(
true
)
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
{
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/authentication/twofactor/presentation/TwoFAPresenter.kt
View file @
0d5bbd04
...
...
@@ -4,9 +4,10 @@ import chat.rocket.android.authentication.domain.model.TokenModel
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.
GetCurrentServerInteractor
import
chat.rocket.android.server.domain.
MultiServerTokenRepository
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.launchUI
import
chat.rocket.common.RocketChatAuthException
...
...
@@ -14,7 +15,9 @@ 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.model.Myself
import
javax.inject.Inject
class
TwoFAPresenter
@Inject
constructor
(
private
val
view
:
TwoFAView
,
...
...
@@ -23,8 +26,12 @@ class TwoFAPresenter @Inject constructor(private val view: TwoFAView,
private
val
multiServerRepository
:
MultiServerTokenRepository
,
private
val
localRepository
:
LocalRepository
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
factory
:
RocketChatClientFactory
)
{
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
factory
:
RocketChatClientFactory
,
private
val
saveAccountInteractor
:
SaveAccountInteractor
,
settingsInteractor
:
GetSettingsInteractor
)
{
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
private
var
settings
:
PublicSettings
=
settingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
// TODO: If the usernameOrEmail and password was informed by the user on the previous screen, then we should pass only the pin, like this: fun authenticate(pin: EditText)
fun
authenticate
(
usernameOrEmail
:
String
,
password
:
String
,
twoFactorAuthenticationCode
:
String
)
{
...
...
@@ -45,6 +52,8 @@ class TwoFAPresenter @Inject constructor(private val view: TwoFAView,
// The token is saved via the client TokenProvider
val
token
=
client
.
login
(
usernameOrEmail
,
password
,
twoFactorAuthenticationCode
)
val
me
=
client
.
me
()
saveAccount
(
me
)
multiServerRepository
.
save
(
server
,
TokenModel
(
token
.
userId
,
token
.
authToken
)
...
...
@@ -80,4 +89,16 @@ class TwoFAPresenter @Inject constructor(private val view: TwoFAView,
}
// TODO: Schedule push token registering when it comes up null
}
private
suspend
fun
saveAccount
(
me
:
Myself
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
logo
=
settings
.
wideTile
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
thumb
=
UrlHelper
.
getAvatarUrl
(
currentServer
,
me
.
username
!!
)
val
account
=
Account
(
currentServer
,
icon
,
logo
,
me
.
username
!!
,
thumb
)
saveAccountInteractor
.
save
(
account
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/twofactor/ui/TwoFAFragment.kt
View file @
0d5bbd04
...
...
@@ -66,7 +66,9 @@ class TwoFAFragment : Fragment(), TwoFAView {
text_two_factor_auth
.
shake
()
}
override
fun
alertInvalidTwoFactorAuthenticationCode
()
=
showMessage
(
getString
(
R
.
string
.
msg_invalid_2fa_code
))
override
fun
alertInvalidTwoFactorAuthenticationCode
()
{
showMessage
(
getString
(
R
.
string
.
msg_invalid_2fa_code
))
}
override
fun
showLoading
()
{
enableUserInput
(
false
)
...
...
@@ -78,9 +80,13 @@ class TwoFAFragment : Fragment(), TwoFAView {
enableUserInput
(
true
)
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/authentication/ui/AuthenticationActivity.kt
View file @
0d5bbd04
package
chat.rocket.android.authentication.ui
import
android.content.Context
import
android.content.Intent
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v7.app.AppCompatActivity
...
...
@@ -19,7 +21,9 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
AndroidInjection
.
inject
(
this
)
presenter
.
loadCredentials
{
authenticated
->
val
newServer
=
intent
.
getBooleanExtra
(
INTENT_ADD_NEW_SERVER
,
false
)
presenter
.
loadCredentials
(
newServer
)
{
authenticated
->
if
(
authenticated
)
{
// just call onCreate, and the presenter will call the navigator...
super
.
onCreate
(
savedInstanceState
)
...
...
@@ -43,4 +47,13 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
ServerFragment
.
newInstance
()
}
}
}
const
val
INTENT_ADD_NEW_SERVER
=
"INTENT_ADD_NEW_SERVER"
fun
Context
.
newServerIntent
():
Intent
{
return
Intent
(
this
,
AuthenticationActivity
::
class
.
java
).
apply
{
putExtra
(
INTENT_ADD_NEW_SERVER
,
true
)
flags
=
Intent
.
FLAG_ACTIVITY_CLEAR_TOP
or
Intent
.
FLAG_ACTIVITY_CLEAR_TASK
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
0d5bbd04
...
...
@@ -229,7 +229,9 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter
.
uploadFile
(
chatRoomId
,
uri
,
""
)
}
override
fun
showInvalidFileMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_invalid_file
))
override
fun
showInvalidFileMessage
()
{
showMessage
(
getString
(
R
.
string
.
msg_invalid_file
))
}
override
fun
showNewMessage
(
message
:
List
<
BaseViewModel
<*
>>)
{
adapter
.
prependData
(
message
)
...
...
@@ -283,9 +285,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override
fun
hideLoading
()
=
view_loading
.
setVisible
(
false
)
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/PinnedMessagesFragment.kt
View file @
0d5bbd04
...
...
@@ -66,9 +66,13 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
override
fun
hideLoading
()
=
view_loading
.
setVisible
(
false
)
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
0d5bbd04
...
...
@@ -135,7 +135,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
private
fun
updateRooms
()
{
Timber
.
d
(
"Updating Rooms"
)
launch
{
launch
(
strategy
.
jobs
)
{
view
.
updateChatRooms
(
getChatRoomsInteractor
.
get
(
currentServer
))
}
}
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
0d5bbd04
...
...
@@ -109,9 +109,13 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
override
fun
hideLoading
()
=
view_loading
.
setVisible
(
false
)
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/dagger/module/ActivityBuilder.kt
View file @
0d5bbd04
...
...
@@ -16,6 +16,8 @@ import chat.rocket.android.main.di.MainModule
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.members.di.MembersFragmentProvider
import
chat.rocket.android.profile.di.ProfileFragmentProvider
import
chat.rocket.android.server.di.ChangeServerModule
import
chat.rocket.android.server.ui.ChangeServerActivity
import
chat.rocket.android.settings.password.di.PasswordFragmentProvider
import
chat.rocket.android.settings.password.ui.PasswordActivity
import
dagger.Module
...
...
@@ -51,4 +53,8 @@ abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector
(
modules
=
[
PasswordFragmentProvider
::
class
])
abstract
fun
bindPasswordActivity
():
PasswordActivity
@PerActivity
@ContributesAndroidInjector
(
modules
=
[
ChangeServerModule
::
class
])
abstract
fun
bindChangeServerActivity
():
ChangeServerActivity
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt
View file @
0d5bbd04
...
...
@@ -240,4 +240,9 @@ class AppModule {
fun
providePermissionInteractor
(
settingsRepository
:
SettingsRepository
,
serverRepository
:
CurrentServerRepository
):
GetPermissionsInteractor
{
return
GetPermissionsInteractor
(
settingsRepository
,
serverRepository
)
}
@Provides
@Singleton
fun
provideAccountsRepository
(
preferences
:
SharedPreferences
,
moshi
:
Moshi
):
AccountsRepository
=
SharedPreferencesAccountsRepository
(
preferences
,
moshi
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
View file @
0d5bbd04
...
...
@@ -14,6 +14,16 @@ object UrlHelper {
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.
*
...
...
app/src/main/java/chat/rocket/android/main/adapter/AccountViewHolder.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.main.adapter
import
android.support.v7.widget.RecyclerView
import
android.view.View
import
chat.rocket.android.server.domain.model.Account
import
kotlinx.android.synthetic.main.item_account.view.*
class
AccountViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
fun
bind
(
account
:
Account
)
{
with
(
itemView
)
{
server_logo
.
setImageURI
(
account
.
serverLogo
)
text_server_url
.
text
=
account
.
serverUrl
text_username
.
text
=
account
.
userName
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/adapter/AccountsAdapter.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.main.adapter
import
android.support.v7.widget.RecyclerView
import
android.view.ViewGroup
import
chat.rocket.android.R
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.util.extensions.inflate
class
AccountsAdapter
(
private
val
accounts
:
List
<
Account
>,
private
val
selector
:
AccountSelector
)
:
RecyclerView
.
Adapter
<
RecyclerView
.
ViewHolder
>()
{
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
RecyclerView
.
ViewHolder
{
return
when
(
viewType
)
{
VIEW_TYPE_ACCOUNT
->
AccountViewHolder
(
parent
.
inflate
(
R
.
layout
.
item_account
))
else
->
AddAccountViewHolder
(
parent
.
inflate
(
R
.
layout
.
item_add_account
))
}
}
override
fun
getItemCount
()
=
accounts
.
size
+
1
override
fun
getItemViewType
(
position
:
Int
)
=
if
(
position
==
accounts
.
size
)
VIEW_TYPE_ADD_ACCOUNT
else
VIEW_TYPE_ACCOUNT
override
fun
onBindViewHolder
(
holder
:
RecyclerView
.
ViewHolder
,
position
:
Int
)
{
when
(
holder
)
{
is
AccountViewHolder
->
bindAccountViewHolder
(
holder
,
position
)
is
AddAccountViewHolder
->
bindAddAccountViewHolder
(
holder
,
position
)
}
}
private
fun
bindAccountViewHolder
(
holder
:
AccountViewHolder
,
position
:
Int
)
{
val
account
=
accounts
[
position
]
holder
.
bind
(
account
)
holder
.
itemView
.
setOnClickListener
{
selector
.
onAccountSelected
(
account
.
serverUrl
)
}
}
private
fun
bindAddAccountViewHolder
(
holder
:
AddAccountViewHolder
,
position
:
Int
)
{
holder
.
itemView
.
setOnClickListener
{
selector
.
onAddedAccountSelected
()
}
}
}
interface
AccountSelector
{
fun
onAccountSelected
(
serverUrl
:
String
)
fun
onAddedAccountSelected
()
}
private
const
val
VIEW_TYPE_ACCOUNT
=
0
private
const
val
VIEW_TYPE_ADD_ACCOUNT
=
1
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/adapter/AddAccountViewHolder.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.main.adapter
import
android.support.v7.widget.RecyclerView
import
android.view.View
class
AddAccountViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/di/MainModule.kt
View file @
0d5bbd04
...
...
@@ -16,7 +16,7 @@ class MainModule {
@Provides
@PerActivity
fun
provideMainNavigator
(
activity
:
MainActivity
,
context
:
Context
)
=
MainNavigator
(
activity
,
context
)
fun
provideMainNavigator
(
activity
:
MainActivity
)
=
MainNavigator
(
activity
)
@Provides
fun
provideMainView
(
activity
:
MainActivity
):
MainView
=
activity
...
...
app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt
View file @
0d5bbd04
...
...
@@ -2,14 +2,16 @@ package chat.rocket.android.main.presentation
import
android.content.Context
import
chat.rocket.android.R
import
chat.rocket.android.authentication.ui.newServerIntent
import
chat.rocket.android.chatroom.ui.chatRoomIntent
import
chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.profile.ui.ProfileFragment
import
chat.rocket.android.server.ui.changeServerIntent
import
chat.rocket.android.settings.ui.SettingsFragment
import
chat.rocket.android.util.extensions.addFragment
class
MainNavigator
(
internal
val
activity
:
MainActivity
,
internal
val
context
:
Context
)
{
class
MainNavigator
(
internal
val
activity
:
MainActivity
)
{
fun
toChatList
()
{
activity
.
addFragment
(
"ChatRoomsFragment"
,
R
.
id
.
fragment_container
)
{
...
...
@@ -35,8 +37,17 @@ class MainNavigator(internal val activity: MainActivity, internal val context: C
isChatRoomReadOnly
:
Boolean
,
chatRoomLastSeen
:
Long
,
isChatRoomSubscribed
:
Boolean
)
{
activity
.
startActivity
(
context
.
chatRoomIntent
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
activity
.
startActivity
(
activity
.
chatRoomIntent
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
isChatRoomReadOnly
,
chatRoomLastSeen
,
isChatRoomSubscribed
))
activity
.
overridePendingTransition
(
R
.
anim
.
open_enter
,
R
.
anim
.
open_exit
)
}
fun
toNewServer
(
serverUrl
:
String
?
=
null
)
{
activity
.
startActivity
(
activity
.
changeServerIntent
(
serverUrl
))
activity
.
finish
()
}
fun
toServerScreen
()
{
activity
.
startActivity
(
activity
.
newServerIntent
())
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt
View file @
0d5bbd04
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.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.main.viewmodel.NavHeaderViewModel
import
chat.rocket.android.main.viewmodel.NavHeaderViewModelMapper
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.realtime.disconnect
import
chat.rocket.core.internal.rest.logout
import
chat.rocket.core.internal.rest.me
import
chat.rocket.core.internal.rest.unregisterPushToken
import
timber.log.Timber
import
javax.inject.Inject
class
MainPresenter
@Inject
constructor
(
private
val
view
:
MainView
,
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
MainNavigator
,
private
val
multiServerRepository
:
MultiServerTokenRepository
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
localRepository
:
LocalRepository
,
private
val
navHeaderMapper
:
NavHeaderViewModelMapper
,
private
val
saveAccountInteractor
:
SaveAccountInteractor
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
,
private
val
removeAccountInterector
:
RemoveAccountInterector
,
getSettingsInteractor
:
GetSettingsInteractor
,
managerFactory
:
ConnectionManagerFactory
,
factory
:
RocketChatClientFactory
)
{
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
manager
=
managerFactory
.
create
(
currentServer
)
private
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
private
var
settings
:
PublicSettings
=
getSettingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
fun
toChatList
()
=
navigator
.
toChatList
()
...
...
@@ -31,6 +43,32 @@ class MainPresenter @Inject constructor(private val view: MainView,
fun
toSettings
()
=
navigator
.
toSettings
()
fun
loadCurrentInfo
()
{
launchUI
(
strategy
)
{
try
{
val
me
=
client
.
me
()
val
model
=
navHeaderMapper
.
mapToViewModel
(
me
)
saveAccount
(
model
)
view
.
setupNavHeader
(
model
,
getAccountsInteractor
.
get
())
}
catch
(
ex
:
Exception
)
{
Timber
.
d
(
ex
,
"Error loading my information for navheader"
)
ex
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
}
}
private
suspend
fun
saveAccount
(
me
:
NavHeaderViewModel
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
account
=
Account
(
currentServer
,
icon
,
me
.
serverLogo
,
me
.
username
,
me
.
avatar
)
saveAccountInteractor
.
save
(
account
)
}
/**
* Logout from current server.
*/
...
...
@@ -39,9 +77,10 @@ class MainPresenter @Inject constructor(private val view: MainView,
try
{
clearTokens
()
client
.
logout
()
//TODO: Add the code to unsubscribe to all subscriptions.
client
.
disconnect
()
view
.
onLogout
()
disconnect
()
removeAccountInterector
.
remove
(
currentServer
)
multiServerRepository
.
clear
(
currentServer
)
navigator
.
toNewServer
()
}
catch
(
exception
:
RocketChatException
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
...
...
@@ -69,4 +108,16 @@ class MainPresenter @Inject constructor(private val view: MainView,
fun
disconnect
()
{
manager
.
disconnect
()
}
fun
changeServer
(
serverUrl
:
String
)
{
if
(
currentServer
!=
serverUrl
)
{
navigator
.
toNewServer
(
serverUrl
)
}
else
{
view
.
closeServerSelection
()
}
}
fun
addNewServer
()
{
navigator
.
toServerScreen
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/presentation/MainView.kt
View file @
0d5bbd04
package
chat.rocket.android.main.presentation
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.android.main.viewmodel.NavHeaderViewModel
import
chat.rocket.android.server.domain.model.Account
interface
MainView
:
MessageView
{
/**
* User has successfully logged out from the current server.
**/
fun
onLogout
()
fun
setupNavHeader
(
model
:
NavHeaderViewModel
,
accounts
:
List
<
Account
>)
fun
closeServerSelection
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt
View file @
0d5bbd04
...
...
@@ -5,12 +5,21 @@ import android.content.Intent
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v7.app.AppCompatActivity
import
android.support.v7.widget.LinearLayoutManager
import
android.view.Gravity
import
android.view.MenuItem
import
android.view.View
import
chat.rocket.android.R
import
chat.rocket.android.authentication.ui.AuthenticationActivity
import
chat.rocket.android.main.adapter.AccountSelector
import
chat.rocket.android.main.adapter.AccountsAdapter
import
chat.rocket.android.main.presentation.MainPresenter
import
chat.rocket.android.main.presentation.MainView
import
chat.rocket.android.main.viewmodel.NavHeaderViewModel
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.util.extensions.fadeIn
import
chat.rocket.android.util.extensions.fadeOut
import
chat.rocket.android.util.extensions.rotateBy
import
chat.rocket.android.util.extensions.showToast
import
dagger.android.AndroidInjection
import
dagger.android.AndroidInjector
...
...
@@ -19,6 +28,8 @@ import dagger.android.HasActivityInjector
import
dagger.android.support.HasSupportFragmentInjector
import
kotlinx.android.synthetic.main.activity_main.*
import
kotlinx.android.synthetic.main.app_bar.*
import
kotlinx.android.synthetic.main.nav_header.view.*
import
timber.log.Timber
import
javax.inject.Inject
class
MainActivity
:
AppCompatActivity
(),
MainView
,
HasActivityInjector
,
HasSupportFragmentInjector
{
...
...
@@ -33,6 +44,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
setContentView
(
R
.
layout
.
activity_main
)
presenter
.
connect
()
presenter
.
loadCurrentInfo
()
setupToolbar
()
setupNavigationView
()
}
...
...
@@ -52,11 +64,45 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
}
}
override
fun
onLogout
()
{
finish
()
val
intent
=
Intent
(
this
,
AuthenticationActivity
::
class
.
java
)
intent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_CLEAR_TASK
or
Intent
.
FLAG_ACTIVITY_NEW_TASK
)
startActivity
(
intent
)
override
fun
setupNavHeader
(
model
:
NavHeaderViewModel
,
accounts
:
List
<
Account
>)
{
Timber
.
d
(
"Setting up nav header: $model"
)
val
headerLayout
=
view_navigation
.
getHeaderView
(
0
)
headerLayout
.
text_name
.
text
=
model
.
username
headerLayout
.
text_server
.
text
=
model
.
server
headerLayout
.
image_avatar
.
setImageURI
(
model
.
avatar
)
headerLayout
.
server_logo
.
setImageURI
(
model
.
serverLogo
)
setupAccountsList
(
headerLayout
,
accounts
)
}
override
fun
closeServerSelection
()
{
}
private
var
expanded
=
false
private
fun
setupAccountsList
(
header
:
View
,
accounts
:
List
<
Account
>)
{
accounts_list
.
layoutManager
=
LinearLayoutManager
(
this
)
accounts_list
.
adapter
=
AccountsAdapter
(
accounts
,
object
:
AccountSelector
{
override
fun
onAccountSelected
(
serverUrl
:
String
)
{
presenter
.
changeServer
(
serverUrl
)
}
override
fun
onAddedAccountSelected
()
{
presenter
.
addNewServer
()
}
})
header
.
account_container
.
setOnClickListener
{
header
.
account_expand
.
rotateBy
(
180f
)
if
(
expanded
)
{
accounts_list
.
fadeOut
()
}
else
{
accounts_list
.
fadeIn
()
}
expanded
=
!
expanded
}
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
...
...
app/src/main/java/chat/rocket/android/main/viewmodel/NavHeaderViewModel.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.main.viewmodel
data class
NavHeaderViewModel
(
val
username
:
String
,
val
server
:
String
,
val
avatar
:
String
?,
val
serverLogo
:
String
?
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/viewmodel/NavHeaderViewModelMapper.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.main.viewmodel
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.server.domain.*
import
chat.rocket.core.model.Myself
import
javax.inject.Inject
class
NavHeaderViewModelMapper
@Inject
constructor
(
serverInteractor
:
GetCurrentServerInteractor
,
getSettingsInteractor
:
GetSettingsInteractor
)
{
private
var
settings
:
PublicSettings
=
getSettingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
private
val
baseUrl
=
settings
.
baseUrl
()
!!
fun
mapToViewModel
(
me
:
Myself
):
NavHeaderViewModel
{
val
username
=
mapUsername
(
me
)
val
thumb
=
me
.
username
?.
let
{
UrlHelper
.
getAvatarUrl
(
baseUrl
,
it
)
}
val
image
=
settings
.
wideTile
()
?:
settings
.
faviconLarge
()
val
logo
=
image
?.
let
{
UrlHelper
.
getServerLogoUrl
(
baseUrl
,
it
)
}
return
NavHeaderViewModel
(
username
,
baseUrl
,
thumb
,
logo
)
}
private
fun
mapUsername
(
me
:
Myself
):
String
{
val
username
=
me
.
username
val
realName
=
me
.
name
val
senderName
=
if
(
settings
.
useRealName
())
realName
else
username
return
senderName
?:
username
.
toString
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/members/ui/MembersFragment.kt
View file @
0d5bbd04
...
...
@@ -96,9 +96,13 @@ class MembersFragment : Fragment(), MembersView {
override
fun
hideLoading
()
=
view_loading
.
setVisible
(
false
)
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/profile/ui/ProfileFragment.kt
View file @
0d5bbd04
...
...
@@ -66,7 +66,9 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
listenToChanges
()
}
override
fun
showProfileUpdateSuccessfullyMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_profile_update_successfully
))
override
fun
showProfileUpdateSuccessfullyMessage
()
{
showMessage
(
getString
(
R
.
string
.
msg_profile_update_successfully
))
}
override
fun
showLoading
()
{
enableUserInput
(
false
)
...
...
@@ -78,9 +80,13 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
enableUserInput
(
true
)
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/server/di/ChangeServerModule.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.server.di
import
android.arch.lifecycle.LifecycleOwner
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerActivity
import
chat.rocket.android.server.presentation.ChangeServerNavigator
import
chat.rocket.android.server.presentation.ChangeServerView
import
chat.rocket.android.server.ui.ChangeServerActivity
import
dagger.Module
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
class
ChangeServerModule
{
@Provides
@PerActivity
fun
provideChangeServerNavigator
(
activity
:
ChangeServerActivity
)
=
ChangeServerNavigator
(
activity
)
@Provides
@PerActivity
fun
ChangeServerView
(
activity
:
ChangeServerActivity
):
ChangeServerView
{
return
activity
}
@Provides
fun
provideLifecycleOwner
(
activity
:
ChangeServerActivity
):
LifecycleOwner
=
activity
@Provides
fun
provideCancelStrategy
(
owner
:
LifecycleOwner
,
jobs
:
Job
):
CancelStrategy
=
CancelStrategy
(
owner
,
jobs
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/AccountsRepository.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.server.domain
import
chat.rocket.android.server.domain.model.Account
interface
AccountsRepository
{
suspend
fun
save
(
account
:
Account
)
suspend
fun
load
():
List
<
Account
>
suspend
fun
remove
(
serverUrl
:
String
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/GetAccountsInteractor.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.server.domain
import
javax.inject.Inject
class
GetAccountsInteractor
@Inject
constructor
(
val
repository
:
AccountsRepository
)
{
suspend
fun
get
()
=
repository
.
load
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/RefreshSettingsInteractor.kt
View file @
0d5bbd04
...
...
@@ -17,11 +17,12 @@ class RefreshSettingsInteractor @Inject constructor(private val factory: RocketC
ACCOUNT_GOOGLE
,
ACCOUNT_FACEBOOK
,
ACCOUNT_GITHUB
,
ACCOUNT_LINKEDIN
,
ACCOUNT_METEOR
,
ACCOUNT_TWITTER
,
ACCOUNT_WORDPRESS
,
ACCOUNT_GITLAB
,
SITE_URL
,
SITE_NAME
,
FAVICON_512
,
USE_REALNAME
,
ALLOW_ROOM_NAME_SPECIAL_CHARS
,
SITE_URL
,
SITE_NAME
,
FAVICON_512
,
FAVICON_196
,
USE_REALNAME
,
ALLOW_ROOM_NAME_SPECIAL_CHARS
,
FAVORITE_ROOMS
,
UPLOAD_STORAGE_TYPE
,
UPLOAD_MAX_FILE_SIZE
,
UPLOAD_WHITELIST_MIMETYPES
,
HIDE_USER_JOIN
,
HIDE_USER_LEAVE
,
HIDE_TYPE_AU
,
HIDE_MUTE_UNMUTE
,
HIDE_TYPE_RU
,
ALLOW_MESSAGE_DELETING
,
ALLOW_MESSAGE_EDITING
,
ALLOW_MESSAGE_PINNING
,
SHOW_DELETED_STATUS
,
SHOW_EDITED_STATUS
)
ALLOW_MESSAGE_EDITING
,
ALLOW_MESSAGE_PINNING
,
SHOW_DELETED_STATUS
,
SHOW_EDITED_STATUS
,
WIDE_TILE_310
)
suspend
fun
refresh
(
server
:
String
)
{
withContext
(
CommonPool
)
{
...
...
app/src/main/java/chat/rocket/android/server/domain/RemoveAccountInterector.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.server.domain
import
javax.inject.Inject
class
RemoveAccountInterector
@Inject
constructor
(
val
repository
:
AccountsRepository
)
{
suspend
fun
remove
(
serverUrl
:
String
)
{
repository
.
remove
(
serverUrl
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/SaveAccountInteractor.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.server.domain
import
chat.rocket.android.server.domain.model.Account
import
javax.inject.Inject
class
SaveAccountInteractor
@Inject
constructor
(
val
repository
:
AccountsRepository
)
{
suspend
fun
save
(
account
:
Account
)
=
repository
.
save
(
account
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/SaveServerInteractor.java
deleted
100644 → 0
View file @
2e7a0037
package
chat
.
rocket
.
android
.
server
.
domain
;
public
class
SaveServerInteractor
{
}
app/src/main/java/chat/rocket/android/server/domain/SettingsRepository.kt
View file @
0d5bbd04
...
...
@@ -29,7 +29,9 @@ const val ACCOUNT_GITLAB = "Accounts_OAuth_Gitlab"
const
val
SITE_URL
=
"Site_Url"
const
val
SITE_NAME
=
"Site_Name"
const
val
FAVICON_196
=
"Assets_favicon_192"
const
val
FAVICON_512
=
"Assets_favicon_512"
const
val
WIDE_TILE_310
=
"Assets_tile_310_wide"
const
val
USE_REALNAME
=
"UI_Use_Real_Name"
const
val
ALLOW_ROOM_NAME_SPECIAL_CHARS
=
"UI_Allow_room_names_with_special_chars"
const
val
FAVORITE_ROOMS
=
"Favorite_Rooms"
...
...
@@ -69,6 +71,9 @@ fun PublicSettings.isGitlabAuthenticationEnabled(): Boolean = this[ACCOUNT_GITLA
fun
PublicSettings
.
isWordpressAuthenticationEnabled
():
Boolean
=
this
[
ACCOUNT_WORDPRESS
]
?.
value
==
true
fun
PublicSettings
.
useRealName
():
Boolean
=
this
[
USE_REALNAME
]
?.
value
==
true
fun
PublicSettings
.
faviconLarge
():
String
?
=
this
[
FAVICON_512
]
?.
value
as
String
?
fun
PublicSettings
.
favicon
():
String
?
=
this
[
FAVICON_196
]
?.
value
as
String
?
fun
PublicSettings
.
wideTile
():
String
?
=
this
[
WIDE_TILE_310
]
?.
value
as
String
?
// Message settings
fun
PublicSettings
.
showDeletedStatus
():
Boolean
=
this
[
SHOW_DELETED_STATUS
]
?.
value
==
true
...
...
app/src/main/java/chat/rocket/android/server/domain/model/Account.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.server.domain.model
import
se.ansman.kotshi.JsonSerializable
@JsonSerializable
data class
Account
(
val
serverUrl
:
String
,
val
serverLogo
:
String
?,
val
serverBg
:
String
?,
val
userName
:
String
,
val
avatar
:
String
?
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/infraestructure/ConnectionManagerFactory.kt
View file @
0d5bbd04
...
...
@@ -19,4 +19,6 @@ class ConnectionManagerFactory @Inject constructor(private val factory: RocketCh
cache
[
url
]
=
manager
return
manager
}
fun
get
(
url
:
String
)
=
cache
[
url
]
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/infraestructure/SharedPreferencesAccountsRepository.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.server.infraestructure
import
android.content.SharedPreferences
import
androidx.content.edit
import
chat.rocket.android.server.domain.AccountsRepository
import
chat.rocket.android.server.domain.model.Account
import
com.squareup.moshi.Moshi
import
com.squareup.moshi.Types
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.withContext
class
SharedPreferencesAccountsRepository
(
private
val
preferences
:
SharedPreferences
,
private
val
moshi
:
Moshi
)
:
AccountsRepository
{
override
suspend
fun
save
(
newAccount
:
Account
)
{
withContext
(
CommonPool
)
{
val
accounts
=
load
()
val
newList
=
accounts
.
filter
{
account
->
newAccount
.
serverUrl
!=
account
.
serverUrl
}
.
toMutableList
()
newList
.
add
(
0
,
newAccount
)
save
(
newList
)
}
}
override
suspend
fun
load
():
List
<
Account
>
=
withContext
(
CommonPool
)
{
val
json
=
preferences
.
getString
(
ACCOUNTS_KEY
,
"[]"
)
val
type
=
Types
.
newParameterizedType
(
List
::
class
.
java
,
Account
::
class
.
java
)
val
adapter
=
moshi
.
adapter
<
List
<
Account
>>(
type
)
adapter
.
fromJson
(
json
)
?:
emptyList
()
}
override
suspend
fun
remove
(
serverUrl
:
String
)
{
withContext
(
CommonPool
)
{
val
accounts
=
load
()
val
newList
=
accounts
.
filter
{
account
->
serverUrl
!=
account
.
serverUrl
}
.
toMutableList
()
save
(
newList
)
}
}
private
fun
save
(
accounts
:
List
<
Account
>)
{
val
type
=
Types
.
newParameterizedType
(
List
::
class
.
java
,
Account
::
class
.
java
)
val
adapter
=
moshi
.
adapter
<
List
<
Account
>>(
type
)
preferences
.
edit
{
putString
(
ACCOUNTS_KEY
,
adapter
.
toJson
(
accounts
))
}
}
}
private
const
val
ACCOUNTS_KEY
=
"ACCOUNTS_KEY"
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/presentation/ChangeServerNavigator.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.server.presentation
import
android.content.Intent
import
chat.rocket.android.authentication.ui.newServerIntent
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.server.ui.ChangeServerActivity
class
ChangeServerNavigator
(
internal
val
activity
:
ChangeServerActivity
)
{
fun
toServerScreen
()
{
activity
.
startActivity
(
activity
.
newServerIntent
())
activity
.
finish
()
}
fun
toChatRooms
()
{
activity
.
startActivity
(
Intent
(
activity
,
MainActivity
::
class
.
java
))
activity
.
finish
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/presentation/ChangeServerPresenter.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.server.presentation
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.common.model.Token
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.TokenRepository
import
javax.inject.Inject
class
ChangeServerPresenter
@Inject
constructor
(
private
val
view
:
ChangeServerView
,
private
val
navigator
:
ChangeServerNavigator
,
private
val
strategy
:
CancelStrategy
,
private
val
saveCurrentServerInteractor
:
SaveCurrentServerInteractor
,
private
val
getCurrentServerInteractor
:
GetCurrentServerInteractor
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
,
private
val
multiServerRepository
:
MultiServerTokenRepository
,
private
val
settingsRepository
:
SettingsRepository
,
private
val
tokenRepository
:
TokenRepository
,
private
val
connectionManager
:
ConnectionManagerFactory
)
{
fun
loadServer
(
newUrl
:
String
?)
{
launchUI
(
strategy
)
{
view
.
showProgress
()
var
url
=
newUrl
if
(
url
==
null
)
{
// Try to load next server on the list...
val
accounts
=
getAccountsInteractor
.
get
()
url
=
accounts
.
firstOrNull
()
?.
serverUrl
}
url
?.
let
{
serverUrl
->
val
token
=
multiServerRepository
.
get
(
serverUrl
)
if
(
token
==
null
)
{
view
.
showInvalidCredentials
()
view
.
hideProgress
()
navigator
.
toServerScreen
()
return
@launchUI
}
val
settings
=
settingsRepository
.
get
(
serverUrl
)
if
(
settings
==
null
)
{
// TODO - reload settings...
}
// Call disconnect on the old url if any...
getCurrentServerInteractor
.
get
()
?.
let
{
url
->
connectionManager
.
get
(
url
)
?.
disconnect
()
}
tokenRepository
.
save
(
Token
(
token
.
userId
,
token
.
authToken
))
saveCurrentServerInteractor
.
save
(
serverUrl
)
view
.
hideProgress
()
navigator
.
toChatRooms
()
}.
ifNull
{
view
.
hideProgress
()
navigator
.
toServerScreen
()
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/presentation/ChangeServerView.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.server.presentation
interface
ChangeServerView
{
fun
showInvalidCredentials
()
fun
showProgress
()
fun
hideProgress
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/ui/ChangeServerActivity.kt
0 → 100644
View file @
0d5bbd04
package
chat.rocket.android.server.ui
import
android.app.ProgressDialog
import
android.content.Context
import
android.content.Intent
import
android.os.Bundle
import
android.support.v7.app.AppCompatActivity
import
chat.rocket.android.server.presentation.ChangeServerPresenter
import
chat.rocket.android.server.presentation.ChangeServerView
import
chat.rocket.android.util.extensions.showToast
import
dagger.android.AndroidInjection
import
javax.inject.Inject
class
ChangeServerActivity
:
AppCompatActivity
(),
ChangeServerView
{
@Inject
lateinit
var
presenter
:
ChangeServerPresenter
var
progress
:
ProgressDialog
?
=
null
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
AndroidInjection
.
inject
(
this
)
super
.
onCreate
(
savedInstanceState
)
val
serverUrl
:
String
?
=
intent
.
getStringExtra
(
INTENT_SERVER_URL
)
presenter
.
loadServer
(
serverUrl
)
}
override
fun
showInvalidCredentials
()
{
showToast
(
"Missing credentials for this server"
)
}
override
fun
showProgress
()
{
progress
=
ProgressDialog
.
show
(
this
,
"Rocket.Chat"
,
"Changing Server"
)
}
override
fun
hideProgress
()
{
progress
?.
dismiss
()
}
}
private
const
val
INTENT_SERVER_URL
=
"INTENT_SERVER_URL"
private
const
val
INTENT_CHAT_ROOM_NAME
=
"INTENT_CHAT_ROOM_NAME"
private
const
val
INTENT_CHAT_ROOM_TYPE
=
"INTENT_CHAT_ROOM_NAME"
fun
Context
.
changeServerIntent
(
serverUrl
:
String
?):
Intent
{
return
Intent
(
this
,
ChangeServerActivity
::
class
.
java
).
apply
{
serverUrl
?.
let
{
url
->
putExtra
(
INTENT_SERVER_URL
,
url
)
}
flags
=
Intent
.
FLAG_ACTIVITY_CLEAR_TOP
or
Intent
.
FLAG_ACTIVITY_CLEAR_TASK
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Animation.kt
View file @
0d5bbd04
...
...
@@ -29,12 +29,12 @@ fun View.fadeIn(startValue: Float = 0f, finishValue: Float = 1f, duration: Long
animate
()
.
alpha
(
startValue
)
.
setDuration
(
duration
)
.
setDuration
(
duration
/
2
)
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
({
animate
()
.
alpha
(
finishValue
)
.
setDuration
(
duration
)
.
setDuration
(
duration
/
2
)
.
setInterpolator
(
AccelerateInterpolator
()).
start
()
}).
start
()
...
...
app/src/main/java/chat/rocket/android/util/extensions/Ui.kt
View file @
0d5bbd04
...
...
@@ -27,7 +27,8 @@ fun View.isVisible(): Boolean {
return
visibility
==
View
.
VISIBLE
}
fun
ViewGroup
.
inflate
(
@LayoutRes
resource
:
Int
):
View
=
LayoutInflater
.
from
(
context
).
inflate
(
resource
,
this
,
false
)
fun
ViewGroup
.
inflate
(
@LayoutRes
resource
:
Int
,
attachToRoot
:
Boolean
=
false
):
View
=
LayoutInflater
.
from
(
context
).
inflate
(
resource
,
this
,
attachToRoot
)
fun
AppCompatActivity
.
addFragment
(
tag
:
String
,
layoutId
:
Int
,
newInstance
:
()
->
Fragment
)
{
val
fragment
=
supportFragmentManager
.
findFragmentByTag
(
tag
)
?:
newInstance
()
...
...
@@ -36,10 +37,12 @@ fun AppCompatActivity.addFragment(tag: String, layoutId: Int, newInstance: () ->
.
commit
()
}
fun
AppCompatActivity
.
addFragmentBackStack
(
tag
:
String
,
layoutId
:
Int
,
newInstance
:
()
->
Fragment
)
{
fun
AppCompatActivity
.
addFragmentBackStack
(
tag
:
String
,
layoutId
:
Int
,
newInstance
:
()
->
Fragment
)
{
val
fragment
=
supportFragmentManager
.
findFragmentByTag
(
tag
)
?:
newInstance
()
supportFragmentManager
.
beginTransaction
()
.
setCustomAnimations
(
R
.
anim
.
enter_from_right
,
R
.
anim
.
exit_to_left
,
R
.
anim
.
enter_from_left
,
R
.
anim
.
exit_to_right
)
.
setCustomAnimations
(
R
.
anim
.
enter_from_right
,
R
.
anim
.
exit_to_left
,
R
.
anim
.
enter_from_left
,
R
.
anim
.
exit_to_right
)
.
replace
(
layoutId
,
fragment
,
tag
)
.
addToBackStack
(
tag
)
.
commit
()
...
...
@@ -50,13 +53,17 @@ fun Activity.hideKeyboard() {
imm
.
hideSoftInputFromWindow
(
currentFocus
.
windowToken
,
InputMethodManager
.
RESULT_UNCHANGED_SHOWN
)
}
fun
Activity
.
showToast
(
@StringRes
resource
:
Int
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
showToast
(
getString
(
resource
),
duration
)
fun
Activity
.
showToast
(
@StringRes
resource
:
Int
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
showToast
(
getString
(
resource
),
duration
)
fun
Activity
.
showToast
(
message
:
String
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
Toast
.
makeText
(
this
,
message
,
duration
).
show
()
fun
Activity
.
showToast
(
message
:
String
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
Toast
.
makeText
(
this
,
message
,
duration
).
show
()
fun
Fragment
.
showToast
(
@StringRes
resource
:
Int
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
showToast
(
getString
(
resource
),
duration
)
fun
Fragment
.
showToast
(
@StringRes
resource
:
Int
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
showToast
(
getString
(
resource
),
duration
)
fun
Fragment
.
showToast
(
message
:
String
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
activity
!!
.
showToast
(
message
,
duration
)
fun
Fragment
.
showToast
(
message
:
String
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
activity
?.
showToast
(
message
,
duration
)
fun
RecyclerView
.
isAtBottom
():
Boolean
{
val
manager
:
RecyclerView
.
LayoutManager
?
=
layoutManager
...
...
app/src/main/res/drawable/black_gradient.xml
0 → 100644
View file @
0d5bbd04
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"rectangle"
>
<gradient
android:angle=
"90"
android:endColor=
"#00000000"
android:centerColor=
"#30000000"
android:startColor=
"#C0000000"
android:type=
"linear"
/>
</shape>
\ No newline at end of file
app/src/main/res/drawable/ic_add_24dp.xml
View file @
0d5bbd04
...
...
@@ -3,9 +3,7 @@
android:height=
"24dp"
android:viewportWidth=
"24.0"
android:viewportHeight=
"24.0"
>
<path
android:fillColor=
"#FF
2F343D
"
android:fillColor=
"#FF
000000
"
android:pathData=
"M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"
/>
</vector>
\ No newline at end of file
</vector>
app/src/main/res/drawable/ic_expand_more_24dp.xml
0 → 100644
View file @
0d5bbd04
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportWidth=
"24.0"
android:viewportHeight=
"24.0"
>
<path
android:fillColor=
"#FF000000"
android:pathData=
"M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"
/>
</vector>
app/src/main/res/layout/activity_main.xml
View file @
0d5bbd04
...
...
@@ -23,11 +23,26 @@
android:layout_height=
"match_parent"
/>
</LinearLayout>
<
android.support.design.widget.NavigationView
android:id=
"@+id/
view_navigation
"
<
FrameLayout
android:id=
"@+id/
navigation_container
"
android:layout_width=
"wrap_content"
android:layout_height=
"match_parent"
android:layout_gravity=
"start"
app:menu=
"@menu/navigation"
/>
android:layout_gravity=
"start"
>
<android.support.design.widget.NavigationView
android:id=
"@+id/view_navigation"
android:layout_width=
"wrap_content"
android:layout_height=
"match_parent"
app:menu=
"@menu/navigation"
app:headerLayout=
"@layout/nav_header"
/>
<android.support.v7.widget.RecyclerView
android:id=
"@+id/accounts_list"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_marginTop=
"@dimen/nav_header_height"
android:elevation=
"20dp"
android:background=
"@color/white"
android:alpha=
"0"
android:visibility=
"gone"
/>
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
\ No newline at end of file
app/src/main/res/layout/item_account.xml
0 → 100644
View file @
0d5bbd04
<?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:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"?selectableItemBackground"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/server_logo"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
android:layout_marginTop=
"8dp"
android:layout_marginStart=
"16dp"
android:layout_marginBottom=
"8dp"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
app:actualImageScaleType=
"centerInside"
/>
<TextView
android:id=
"@+id/text_server_url"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"8dp"
android:layout_marginEnd=
"16dp"
android:textStyle=
"bold"
app:layout_constraintTop_toTopOf=
"@id/server_logo"
app:layout_constraintStart_toEndOf=
"@id/server_logo"
app:layout_constraintEnd_toEndOf=
"parent"
tools:text=
"https://open.rocket.chat"
/>
<TextView
android:id=
"@+id/text_username"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"8dp"
android:layout_marginEnd=
"16dp"
app:layout_constraintBottom_toBottomOf=
"@id/server_logo"
app:layout_constraintStart_toEndOf=
"@id/server_logo"
app:layout_constraintEnd_toEndOf=
"parent"
tools:text=
"Lucio Maciel"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/item_add_account.xml
0 → 100644
View file @
0d5bbd04
<?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:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"?selectableItemBackground"
>
<ImageView
android:id=
"@+id/server_logo"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
android:layout_marginTop=
"8dp"
android:layout_marginStart=
"16dp"
android:layout_marginBottom=
"8dp"
android:src=
"@drawable/ic_add_24dp"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"8dp"
android:layout_marginEnd=
"16dp"
android:textAppearance=
"@style/TextAppearance.AppCompat.Medium"
android:text=
"@string/add_account"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintStart_toEndOf=
"@id/server_logo"
app:layout_constraintEnd_toEndOf=
"parent"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/nav_header.xml
0 → 100644
View file @
0d5bbd04
<?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:layout_width=
"match_parent"
android:layout_height=
"@dimen/nav_header_height"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/server_logo"
android:layout_width=
"0dp"
android:layout_height=
"0dp"
android:foreground=
"@drawable/black_gradient"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:actualImageScaleType=
"centerCrop"
tools:src=
"@tools:sample/backgrounds/scenic"
/>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_avatar"
android:layout_width=
"60dp"
android:layout_height=
"60dp"
android:layout_marginStart=
"16dp"
android:layout_marginTop=
"16dp"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:roundedCornerRadius=
"3dp"
tools:src=
"@tools:sample/avatars"
/>
<android.support.constraint.ConstraintLayout
android:id=
"@+id/account_container"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"8dp"
android:layout_marginStart=
"12dp"
android:layout_marginEnd=
"12dp"
android:layout_marginTop=
"16dp"
android:padding=
"4dp"
android:elevation=
"2dp"
android:background=
"?selectableItemBackground"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintStart_toStartOf=
"@+id/image_avatar"
app:layout_constraintTop_toBottomOf=
"@+id/image_avatar"
>
<TextView
android:id=
"@+id/text_name"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginEnd=
"8dp"
android:textAppearance=
"@style/TextAppearance.AppCompat.Medium"
android:textColor=
"@color/white"
app:layout_constraintEnd_toStartOf=
"@+id/account_expand"
app:layout_constraintStart_toStartOf=
"parent"
tools:text=
"Lucio Maciel"
/>
<TextView
android:id=
"@+id/text_server"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginEnd=
"8dp"
android:textAppearance=
"@style/TextAppearance.AppCompat.Small"
android:textColor=
"@color/white"
app:layout_constraintEnd_toStartOf=
"@+id/account_expand"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/text_name"
tools:text=
"https://open.rocket.chat"
/>
<ImageView
android:id=
"@+id/account_expand"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginEnd=
"8dp"
android:src=
"@drawable/ic_expand_more_24dp"
android:tint=
"@color/whitesmoke"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/values/colors.xml
View file @
0d5bbd04
...
...
@@ -34,6 +34,8 @@
<color
name=
"actionMenuColor"
>
#FF727272
</color>
<color
name=
"whitesmoke"
>
#FFf1f1f1
</color>
<color
name=
"translucent_white"
>
#70F1F1F1
</color>
<color
name=
"colorEmojiIcon"
>
#FF767676
</color>
<!-- Suggestions -->
...
...
app/src/main/res/values/dimens.xml
View file @
0d5bbd04
...
...
@@ -35,5 +35,6 @@
<!-- Autocomplete Popup -->
<dimen
name=
"popup_max_height"
>
150dp
</dimen>
<dimen
name=
"suggestions_box_max_height"
>
250dp
</dimen>
<dimen
name=
"nav_header_height"
>
160dp
</dimen>
</resources>
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
0d5bbd04
...
...
@@ -138,5 +138,6 @@
<string
name=
"Join_the_given_channel"
>
Join the given channel
</string>
<string
name=
"Guggy_Command_Description"
>
Generates a gif based upon the provided text
</string>
<string
name=
"Slash_Topic_Description"
>
Set topic
</string>
<string
name=
"add_account"
>
Add Account
</string>
</resources>
\ No newline at end of file
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