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
6a1f37b7
Commit
6a1f37b7
authored
Jan 15, 2018
by
Leonardo Aramaki
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop-2.x' into spotlight-on-toolbar
parents
c4554625
8fef2381
Changes
62
Hide whitespace changes
Inline
Side-by-side
Showing
62 changed files
with
1036 additions
and
369 deletions
+1036
-369
.gitignore
.gitignore
+4
-2
build-sdk.sh
app/build-sdk.sh
+1
-1
build.gradle
app/build.gradle
+7
-12
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+6
-6
ChatRoomActivity.kt
...src/main/java/chat/rocket/android/app/ChatRoomActivity.kt
+0
-19
DrawableHelper.kt
app/src/main/java/chat/rocket/android/app/DrawableHelper.kt
+1
-1
Message.kt
...src/main/java/chat/rocket/android/app/chatroom/Message.kt
+0
-9
MessageFragment.kt
.../java/chat/rocket/android/app/chatroom/MessageFragment.kt
+0
-53
MessageListAdapter.kt
...va/chat/rocket/android/app/chatroom/MessageListAdapter.kt
+0
-60
AuthenticationModule.kt
.../rocket/android/authentication/di/AuthenticationModule.kt
+1
-7
LoginFragmentProvider.kt
.../android/authentication/login/di/LoginFragmentProvider.kt
+2
-2
LoginPresenter.kt
...droid/authentication/login/presentation/LoginPresenter.kt
+5
-9
LoginFragment.kt
...t/rocket/android/authentication/login/ui/LoginFragment.kt
+2
-9
AuthenticationNavigator.kt
...id/authentication/presentation/AuthenticationNavigator.kt
+1
-0
ServerFragmentProvider.kt
...ndroid/authentication/server/di/ServerFragmentProvider.kt
+1
-1
ServerPresenter.kt
...oid/authentication/server/presentation/ServerPresenter.kt
+39
-28
ServerView.kt
.../android/authentication/server/presentation/ServerView.kt
+7
-1
ServerFragment.kt
...rocket/android/authentication/server/ui/ServerFragment.kt
+2
-0
SignupPresenter.kt
...oid/authentication/signup/presentation/SignupPresenter.kt
+10
-9
TwoFAPresenter.kt
...d/authentication/twofactor/presentation/TwoFAPresenter.kt
+31
-31
AuthenticationActivity.kt
...ocket/android/authentication/ui/AuthenticationActivity.kt
+1
-1
ChatRoomFragmentModule.kt
...chat/rocket/android/chatroom/di/ChatRoomFragmentModule.kt
+30
-0
ChatRoomFragmentProvider.kt
...at/rocket/android/chatroom/di/ChatRoomFragmentProvider.kt
+12
-0
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+51
-0
ChatRoomView.kt
...chat/rocket/android/chatroom/presentation/ChatRoomView.kt
+30
-0
ChatRoomActivity.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
+81
-0
ChatRoomAdapter.kt
...n/java/chat/rocket/android/chatroom/ui/ChatRoomAdapter.kt
+73
-0
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+119
-0
ChatRoomsFragmentModule.kt
...at/rocket/android/chatrooms/di/ChatRoomsFragmentModule.kt
+0
-5
ChatRoomsModule.kt
.../java/chat/rocket/android/chatrooms/di/ChatRoomsModule.kt
+16
-0
ChatRoomsNavigator.kt
...cket/android/chatrooms/presentation/ChatRoomsNavigator.kt
+14
-0
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+17
-14
ChatRoomsAdapter.kt
...java/chat/rocket/android/chatrooms/ui/ChatRoomsAdapter.kt
+69
-56
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+9
-3
ActivityBuilder.kt
...java/chat/rocket/android/dagger/module/ActivityBuilder.kt
+9
-1
AppModule.kt
.../main/java/chat/rocket/android/dagger/module/AppModule.kt
+7
-1
EndlessRecyclerViewScrollListener.kt
...ocket/android/helper/EndlessRecyclerViewScrollListener.kt
+110
-0
UrlHelper.kt
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
+42
-3
ChatRoomsRepository.kt
.../chat/rocket/android/server/domain/ChatRoomsRepository.kt
+2
-0
SaveChatRoomsInteractor.kt
...t/rocket/android/server/domain/SaveChatRoomsInteractor.kt
+1
-0
SaveSettingsInteractor.kt
...at/rocket/android/server/domain/SaveSettingsInteractor.kt
+1
-0
accelerate_cubic.xml
app/src/main/res/anim/accelerate_cubic.xml
+3
-0
close_enter.xml
app/src/main/res/anim/close_enter.xml
+23
-0
close_exit.xml
app/src/main/res/anim/close_exit.xml
+9
-0
decelerate_cubic.xml
app/src/main/res/anim/decelerate_cubic.xml
+3
-0
open_enter.xml
app/src/main/res/anim/open_enter.xml
+9
-0
open_exit.xml
app/src/main/res/anim/open_exit.xml
+23
-0
ic_help_black_24dp.xml
app/src/main/res/drawable/ic_help_black_24dp.xml
+9
-0
activity_authentication.xml
app/src/main/res/layout/activity_authentication.xml
+3
-1
activity_chat_room.xml
app/src/main/res/layout/activity_chat_room.xml
+4
-2
activity_main.xml
app/src/main/res/layout/activity_main.xml
+3
-1
app_bar_chat_room.xml
app/src/main/res/layout/app_bar_chat_room.xml
+49
-0
avatar.xml
app/src/main/res/layout/avatar.xml
+25
-0
fragment_authentication_server.xml
app/src/main/res/layout/fragment_authentication_server.xml
+1
-0
fragment_chat_room.xml
app/src/main/res/layout/fragment_chat_room.xml
+12
-0
item_chat.xml
app/src/main/res/layout/item_chat.xml
+8
-4
item_message.xml
app/src/main/res/layout/item_message.xml
+10
-7
message_composer.xml
app/src/main/res/layout/message_composer.xml
+11
-0
strings.xml
app/src/main/res/values-pt-rBR/strings.xml
+6
-3
strings.xml
app/src/main/res/values/strings.xml
+5
-2
build.gradle
build.gradle
+1
-0
dependencies.gradle
dependencies.gradle
+5
-5
No files found.
.gitignore
View file @
6a1f37b7
# Auth files
*.jks
app/rocket-chat.json
app/src/release/google-services.json
app/src/release/res/values/api_key_strings.xml
app/libs/
# Auth files
*.jks
################################# Created by https://www.gitignore.io/api/androidstudio (modified) #################################
...
...
app/build-sdk.sh
View file @
6a1f37b7
...
...
@@ -98,4 +98,4 @@ cp -v $SDK_DIR/core/build/libs/core-0.1-SNAPSHOT.jar $CURRENT_DIR/libs/core-$SHA
echo
"
$SHA
"
>
$SDK_DIR
/.last_commit_hash
exit
0
exit
0
\ No newline at end of file
app/build.gradle
View file @
6a1f37b7
...
...
@@ -34,7 +34,7 @@ android {
}
dependencies
{
implementation
fileTree
(
dir:
'libs'
,
include:
[
'*.jar'
]
)
implementation
fileTree
(
include:
[
'*.jar'
],
dir:
'libs'
)
implementation
project
(
':player'
)
...
...
@@ -52,9 +52,7 @@ dependencies {
implementation
libraries
.
daggerSupport
kapt
libraries
.
daggerProcessor
kapt
libraries
.
daggerAndroidApt
implementation
libraries
.
moshi
implementation
libraries
.
kotshi
implementation
libraries
.
playServicesGcm
implementation
libraries
.
room
kapt
libraries
.
roomProcessor
...
...
@@ -63,6 +61,7 @@ dependencies {
implementation
libraries
.
rxjava
implementation
libraries
.
rxandroid
implementation
libraries
.
moshi
implementation
libraries
.
okhttp
implementation
libraries
.
okhttpLogger
...
...
@@ -76,26 +75,22 @@ dependencies {
implementation
libraries
.
frescoImageViewer
implementation
libraries
.
kotshi
implementation
libraries
.
floatingSearchView
implementation
libraries
.
androidSvg
implementation
libraries
.
playServicesGcm
implementation
libraries
.
aVLoadingIndicatorView
implementation
libraries
.
textDrawable
testImplementation
libraries
.
junit
androidTestImplementation
(
libraries
.
expressoCore
,
{
androidTestImplementation
(
libraries
.
expressoCore
,
{
exclude
group:
'com.android.support'
,
module:
'support-annotations'
})
}
repositories
{
mavenCentral
()
}
kotlin
{
experimental
{
coroutines
"enable"
...
...
@@ -109,4 +104,4 @@ task compileSdk(type:Exec) {
}
preBuild
.
dependsOn
compileSdk
apply
plugin:
'com.google.gms.google-services'
apply
plugin:
'com.google.gms.google-services'
\ No newline at end of file
app/src/main/AndroidManifest.xml
View file @
6a1f37b7
...
...
@@ -36,13 +36,17 @@
</intent-filter>
</activity>
<activity
android:name=
".webview.WebViewActivity"
android:theme=
"@style/AppTheme"
/>
<activity
android:name=
".chatrooms.ui.MainActivity"
android:theme=
"@style/ChatListTheme"
/>
<activity
android:name=
".
app
.ChatRoomActivity"
android:theme=
"@style/AppTheme"
></activity
>
android:name=
".
chatroom.ui
.ChatRoomActivity"
android:theme=
"@style/AppTheme"
/
>
<receiver
android:name=
"com.google.android.gms.gcm.GcmReceiver"
...
...
@@ -71,10 +75,6 @@
<action
android:name=
"com.google.android.c2dm.intent.RECEIVE"
/>
</intent-filter>
</service>
<activity
android:name=
".webview.WebViewActivity"
android:theme=
"@style/AppTheme"
/>
</application>
</manifest>
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/ChatRoomActivity.kt
deleted
100644 → 0
View file @
c4554625
package
chat.rocket.android.app
import
android.os.Bundle
import
android.support.v7.app.AppCompatActivity
import
chat.rocket.android.R
import
chat.rocket.android.app.chatroom.MessageFragment
import
chat.rocket.android.util.addFragment
class
ChatRoomActivity
:
AppCompatActivity
()
{
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
setContentView
(
R
.
layout
.
activity_chat_room
)
addFragment
(
"MessageFragment"
,
R
.
id
.
fragment_container
)
{
MessageFragment
()
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/DrawableHelper.kt
View file @
6a1f37b7
...
...
@@ -135,7 +135,7 @@ object DrawableHelper {
.
beginConfig
()
.
useFont
(
Typeface
.
SANS_SERIF
)
.
endConfig
()
.
buildRound
(
TextHelper
.
getFirstCharacter
(
string
),
getAvatarBackgroundColor
(
string
)
)
.
buildRound
Rect
(
TextHelper
.
getFirstCharacter
(
string
),
getAvatarBackgroundColor
(
string
),
4
)
}
/**
...
...
app/src/main/java/chat/rocket/android/app/chatroom/Message.kt
deleted
100644 → 0
View file @
c4554625
package
chat.rocket.android.app.chatroom
import
chat.rocket.android.app.User
import
org.threeten.bp.LocalDateTime
data class
Message
(
val
user
:
User
,
val
textContent
:
String
?,
val
imageAttachmentUri
:
String
?,
val
localDatetime
:
LocalDateTime
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/chatroom/MessageFragment.kt
deleted
100644 → 0
View file @
c4554625
package
chat.rocket.android.app.chatroom
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v7.widget.LinearLayoutManager
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
chat.rocket.android.R
import
chat.rocket.android.app.User
import
kotlinx.android.synthetic.main.fragment_chat_rooms.*
import
org.threeten.bp.LocalDateTime
class
MessageFragment
:
Fragment
()
{
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
inflater
.
inflate
(
R
.
layout
.
fragment_message
,
container
,
false
)
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
showMessageList
(
createDumpData
())
}
// This is just a sample showing 2 messages in the chat room. We need to get it rid in a real word. REMARK: remove this comment and this method.
private
fun
createDumpData
():
List
<
Message
>
{
val
user1
=
User
(
"1"
,
"Filipe Brito"
,
"filipe.brito"
,
"online"
,
"https://open.rocket.chat/avatar/filipe.brito"
)
val
user2
=
User
(
"2"
,
"Lucio Maciel"
,
"Lucio Maciel"
,
"busy"
,
"https://open.rocket.chat/avatar/lucio.maciel"
)
val
message1
=
Message
(
user1
,
"This is a multiline chat message from Bertie that will take more than just one line of text. I have sure that everything is amazing!"
,
"https://rocket.chat/images/index/livechat.png"
,
LocalDateTime
.
now
())
val
message2
=
Message
(
user2
,
"Great!"
,
"https://rocket.chat/images/index/screenshot.png"
,
LocalDateTime
.
now
().
plusHours
(
1
))
return
listOf
(
message1
,
message2
)
}
// REMARK: The presenter should call this method.
private
fun
showMessageList
(
dataSet
:
List
<
Message
>)
{
activity
?.
apply
{
recycler_view
.
layoutManager
=
LinearLayoutManager
(
this
,
LinearLayoutManager
.
VERTICAL
,
false
)
recycler_view
.
adapter
=
MessageListAdapter
(
this
,
dataSet
.
toMutableList
())
{}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/chatroom/MessageListAdapter.kt
deleted
100644 → 0
View file @
c4554625
package
chat.rocket.android.app.chatroom
import
DateTimeHelper
import
android.content.Context
import
android.support.v7.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
android.widget.TextView
import
chat.rocket.android.R
import
com.facebook.drawee.view.SimpleDraweeView
import
com.stfalcon.frescoimageviewer.ImageViewer
import
kotlinx.android.synthetic.main.item_message.view.*
class
MessageListAdapter
(
private
val
context
:
Context
,
private
var
dataSet
:
MutableList
<
Message
>,
private
val
listener
:
(
Message
)
->
Unit
)
:
RecyclerView
.
Adapter
<
MessageListAdapter
.
ViewHolder
>()
{
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
ViewHolder
{
val
view
=
LayoutInflater
.
from
(
parent
.
context
).
inflate
(
R
.
layout
.
item_message
,
parent
,
false
)
return
ViewHolder
(
view
)
}
override
fun
onBindViewHolder
(
holder
:
ViewHolder
,
position
:
Int
)
{
val
message
=
dataSet
[
position
]
holder
.
userAvatar
.
setImageURI
(
message
.
user
.
avatarUri
)
holder
.
userName
.
text
=
message
.
user
.
name
holder
.
time
.
text
=
DateTimeHelper
.
getTime
(
message
.
localDatetime
)
val
textContent
=
message
.
textContent
if
(
textContent
.
isNullOrBlank
())
{
holder
.
textContent
.
visibility
=
View
.
GONE
}
else
{
holder
.
textContent
.
text
=
textContent
}
val
imageAttachmentUri
=
message
.
imageAttachmentUri
if
(
imageAttachmentUri
.
isNullOrBlank
())
{
holder
.
imageAttachment
.
visibility
=
View
.
GONE
}
else
{
holder
.
imageAttachment
.
setImageURI
(
imageAttachmentUri
)
holder
.
imageAttachment
.
setOnClickListener
({
ImageViewer
.
Builder
(
context
,
listOf
(
imageAttachmentUri
))
.
hideStatusBar
(
false
)
.
show
()
})
}
}
override
fun
getItemCount
():
Int
=
dataSet
.
size
class
ViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
val
userAvatar
:
SimpleDraweeView
=
itemView
.
image_user_avatar
val
userName
:
TextView
=
itemView
.
text_user_name
val
time
:
TextView
=
itemView
.
text_message_time
val
textContent
:
TextView
=
itemView
.
text_content
val
imageAttachment
:
SimpleDraweeView
=
itemView
.
image_attachment
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/di/AuthenticationModule.kt
View file @
6a1f37b7
...
...
@@ -6,7 +6,6 @@ import chat.rocket.android.authentication.ui.AuthenticationActivity
import
chat.rocket.android.dagger.scope.PerActivity
import
dagger.Module
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
class
AuthenticationModule
{
...
...
@@ -14,9 +13,4 @@ class AuthenticationModule {
@Provides
@PerActivity
fun
provideAuthenticationNavigator
(
activity
:
AuthenticationActivity
,
context
:
Context
)
=
AuthenticationNavigator
(
activity
,
context
)
@Provides
fun
provideJob
():
Job
{
return
Job
()
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/login/di/LoginFragmentProvider.kt
View file @
6a1f37b7
...
...
@@ -6,6 +6,6 @@ import dagger.android.ContributesAndroidInjector
@Module
abstract
class
LoginFragmentProvider
{
@ContributesAndroidInjector
(
modules
=
arrayOf
(
LoginFragmentModule
::
class
)
)
@ContributesAndroidInjector
(
modules
=
[(
LoginFragmentModule
::
class
)]
)
abstract
fun
provideLoginFragment
():
LoginFragment
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/login/presentation/LoginPresenter.kt
View file @
6a1f37b7
...
...
@@ -15,7 +15,6 @@ import chat.rocket.core.internal.rest.login
import
chat.rocket.core.internal.rest.registerPushToken
import
javax.inject.Inject
class
LoginPresenter
@Inject
constructor
(
private
val
view
:
LoginView
,
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
AuthenticationNavigator
,
...
...
@@ -23,7 +22,6 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
private
val
settingsInteractor
:
GetSettingsInteractor
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
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
()
!!
)
...
...
@@ -40,6 +38,8 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
return
}
view
.
showSignUpView
(
settings
.
registrationEnabled
())
var
hasSocial
=
false
if
(
settings
.
facebookEnabled
())
{
view
.
enableLoginByFacebook
()
...
...
@@ -69,8 +69,6 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
view
.
enableLoginByGitlab
()
hasSocial
=
true
}
view
.
showSignUpView
(
settings
.
registrationEnabled
())
view
.
showOauthView
(
hasSocial
)
}
...
...
@@ -108,9 +106,9 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
}
}
}
}
finally
{
view
.
hideLoading
()
}
view
.
hideLoading
()
}
else
{
view
.
showNoInternetConnection
()
}
...
...
@@ -119,9 +117,7 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
}
}
fun
signup
()
{
navigator
.
toSignUp
()
}
fun
signup
()
=
navigator
.
toSignUp
()
private
suspend
fun
registerPushToken
()
{
localRepository
.
get
(
LocalRepository
.
KEY_PUSH_TOKEN
)
?.
let
{
...
...
app/src/main/java/chat/rocket/android/authentication/login/ui/LoginFragment.kt
View file @
6a1f37b7
...
...
@@ -8,7 +8,6 @@ import android.support.v4.app.Fragment
import
android.text.style.ClickableSpan
import
android.view.*
import
android.widget.ImageButton
import
android.view.inputmethod.InputMethodManager
import
android.widget.ScrollView
import
android.widget.Toast
import
chat.rocket.android.R
...
...
@@ -57,12 +56,6 @@ class LoginFragment : Fragment(), LoginView {
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
activity
?.
apply
{
text_username_or_email
.
requestFocus
()
val
imm
=
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
)
as
InputMethodManager
imm
.
showSoftInput
(
text_username_or_email
,
InputMethodManager
.
SHOW_IMPLICIT
)
}
if
(
Build
.
VERSION
.
SDK_INT
<=
Build
.
VERSION_CODES
.
M
)
{
tintEditTextDrawableStart
()
}
...
...
@@ -201,7 +194,7 @@ class LoginFragment : Fragment(), LoginView {
private
fun
setupSignUpListener
()
{
val
signUp
=
getString
(
R
.
string
.
title_sign_up
)
val
newToRocketChat
=
String
.
format
(
getString
(
R
.
string
.
msg_new_
to_rocket_chat
),
signUp
)
val
newToRocketChat
=
String
.
format
(
getString
(
R
.
string
.
msg_new_
user
),
signUp
)
text_new_to_rocket_chat
.
text
=
newToRocketChat
...
...
@@ -216,7 +209,7 @@ class LoginFragment : Fragment(), LoginView {
button_log_in
.
isEnabled
=
value
text_username_or_email
.
isEnabled
=
value
text_password
.
isEnabled
=
value
if
(
isEditTextEmpty
())
{
if
(
!
isEditTextEmpty
())
{
showSignUpView
(
value
)
showOauthView
(
value
)
}
...
...
app/src/main/java/chat/rocket/android/authentication/presentation/AuthenticationNavigator.kt
View file @
6a1f37b7
...
...
@@ -32,6 +32,7 @@ class AuthenticationNavigator(internal val activity: AuthenticationActivity, int
fun
toWebPage
(
url
:
String
)
{
activity
.
startActivity
(
context
.
webViewIntent
(
url
))
activity
.
overridePendingTransition
(
R
.
anim
.
slide_up
,
R
.
anim
.
hold
)
}
fun
toChatList
()
{
...
...
app/src/main/java/chat/rocket/android/authentication/server/di/ServerFragmentProvider.kt
View file @
6a1f37b7
...
...
@@ -6,6 +6,6 @@ import dagger.android.ContributesAndroidInjector
@Module
abstract
class
ServerFragmentProvider
{
@ContributesAndroidInjector
(
modules
=
arrayOf
(
ServerFragmentModule
::
class
)
)
@ContributesAndroidInjector
(
modules
=
[(
ServerFragmentModule
::
class
)]
)
abstract
fun
provideServerFragment
():
ServerFragment
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/server/presentation/ServerPresenter.kt
View file @
6a1f37b7
...
...
@@ -3,9 +3,11 @@ 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.*
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.launchUI
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.settings
import
java.security.InvalidParameterException
...
...
@@ -17,41 +19,50 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
private
val
serverInteractor
:
SaveCurrentServerInteractor
,
private
val
settingsInteractor
:
SaveSettingsInteractor
,
private
val
factory
:
RocketChatClientFactory
)
{
private
var
settingsFilter
=
arrayOf
(
SITE_URL
,
SITE_NAME
,
FAVICON_512
,
USE_REALNAME
,
ALLOW_ROOM_NAME_SPECIAL_CHARS
,
FAVORITE_ROOMS
,
ACCOUNT_LOGIN_FORM
,
ACCOUNT_GOOGLE
,
ACCOUNT_FACEBOOK
,
ACCOUNT_GITHUB
,
ACCOUNT_GITLAB
,
ACCOUNT_LINKEDIN
,
ACCOUNT_METEOR
,
ACCOUNT_TWITTER
,
ACCOUNT_WORDPRESS
,
LDAP_ENABLE
,
ACCOUNT_REGISTRATION
,
STORAGE_TYPE
,
HIDE_USER_JOIN
,
HIDE_USER_LEAVE
,
HIDE_TYPE_AU
,
private
lateinit
var
client
:
RocketChatClient
private
var
settingsFilter
=
arrayOf
(
SITE_URL
,
SITE_NAME
,
FAVICON_512
,
USE_REALNAME
,
ALLOW_ROOM_NAME_SPECIAL_CHARS
,
FAVORITE_ROOMS
,
ACCOUNT_LOGIN_FORM
,
ACCOUNT_GOOGLE
,
ACCOUNT_FACEBOOK
,
ACCOUNT_GITHUB
,
ACCOUNT_GITLAB
,
ACCOUNT_LINKEDIN
,
ACCOUNT_METEOR
,
ACCOUNT_TWITTER
,
ACCOUNT_WORDPRESS
,
LDAP_ENABLE
,
ACCOUNT_REGISTRATION
,
STORAGE_TYPE
,
HIDE_USER_JOIN
,
HIDE_USER_LEAVE
,
HIDE_TYPE_AU
,
HIDE_MUTE_UNMUTE
,
HIDE_TYPE_RU
,
ACCOUNT_CUSTOM_FIELDS
)
fun
connect
(
server
:
String
)
{
var
cli
:
RocketChatClient
?
=
null
try
{
cli
=
factory
.
create
(
server
)
}
catch
(
ex
:
InvalidParameterException
)
{
view
.
showMessage
(
ex
.
message
!!
)
}
if
(!
UrlHelper
.
isValidUrl
(
server
))
{
view
.
showInvalidServerUrl
()
}
else
{
try
{
client
=
factory
.
create
(
server
)
}
catch
(
exception
:
InvalidParameterException
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
return
}
cli
?.
let
{
c
lient
->
launchUI
(
strategy
)
{
if
(
NetworkHelper
.
hasInternetAccess
())
{
view
.
showLoading
()
client
.
let
{
rocketChatC
lient
->
launchUI
(
strategy
)
{
if
(
NetworkHelper
.
hasInternetAccess
())
{
view
.
showLoading
()
try
{
val
settings
=
c
lient
.
settings
(*
settingsFilter
)
settingsInteractor
.
save
(
server
,
settings
)
serverInteractor
.
save
(
server
)
try
{
val
settings
=
rocketChatC
lient
.
settings
(*
settingsFilter
)
settingsInteractor
.
save
(
server
,
settings
)
serverInteractor
.
save
(
server
)
navigator
.
toLogin
()
}
catch
(
ex
:
Exception
)
{
ex
.
printStackTrace
()
view
.
showMessage
(
ex
.
message
!!
)
}
finally
{
view
.
hideLoading
()
navigator
.
toLogin
()
}
catch
(
exception
:
Exception
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
finally
{
view
.
hideLoading
()
}
}
else
{
view
.
showNoInternetConnection
()
}
}
else
{
view
.
showNoInternetConnection
()
}
}
}
...
...
app/src/main/java/chat/rocket/android/authentication/server/presentation/ServerView.kt
View file @
6a1f37b7
...
...
@@ -4,4 +4,10 @@ import chat.rocket.android.core.behaviours.InternetView
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.MessageView
interface
ServerView
:
LoadingView
,
MessageView
,
InternetView
\ No newline at end of file
interface
ServerView
:
LoadingView
,
MessageView
,
InternetView
{
/**
* Notifies the user about an invalid inputted server URL.
*/
fun
showInvalidServerUrl
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/server/ui/ServerFragment.kt
View file @
6a1f37b7
...
...
@@ -44,6 +44,8 @@ class ServerFragment : Fragment(), ServerView {
relative_layout
.
viewTreeObserver
.
removeOnGlobalLayoutListener
(
layoutListener
)
}
override
fun
showInvalidServerUrl
()
=
showMessage
(
getString
(
R
.
string
.
msg_invalid_server_url
))
override
fun
showLoading
()
{
enableUserInput
(
false
)
view_loading
.
setVisibility
(
true
)
...
...
app/src/main/java/chat/rocket/android/authentication/signup/presentation/SignupPresenter.kt
View file @
6a1f37b7
...
...
@@ -3,11 +3,13 @@ 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.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.launchUI
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.registerPushToken
...
...
@@ -20,7 +22,6 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
private
val
localRepository
:
LocalRepository
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
factory
:
RocketChatClientFactory
)
{
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
fun
signup
(
name
:
String
,
username
:
String
,
password
:
String
,
email
:
String
)
{
...
...
@@ -53,15 +54,15 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
registerPushToken
()
navigator
.
toChatList
()
}
catch
(
exception
:
RocketChatException
)
{
val
errorMessage
=
exception
.
message
if
(
errorMessage
!=
null
)
{
view
.
showMessage
(
errorMessage
)
}
else
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
}
finally
{
view
.
hideLoading
()
view
.
hideLoading
()
}
}
else
{
view
.
showNoInternetConnection
()
}
...
...
@@ -72,13 +73,13 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
fun
termsOfService
()
{
serverInteractor
.
get
()
?.
let
{
navigator
.
toWebPage
(
"/terms-of-service"
)
navigator
.
toWebPage
(
UrlHelper
.
getTermsOfServiceUrl
(
it
)
)
}
}
fun
privacyPolicy
()
{
serverInteractor
.
get
()
?.
let
{
navigator
.
toWebPage
(
"/privacy-policy"
)
navigator
.
toWebPage
(
UrlHelper
.
getPrivacyPolicyUrl
(
it
)
)
}
}
...
...
app/src/main/java/chat/rocket/android/authentication/twofactor/presentation/TwoFAPresenter.kt
View file @
6a1f37b7
...
...
@@ -9,6 +9,7 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.launchUI
import
chat.rocket.common.RocketChatAuthException
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.registerPushToken
...
...
@@ -20,51 +21,50 @@ class TwoFAPresenter @Inject constructor(private val view: TwoFAView,
private
val
localRepository
:
LocalRepository
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
factory
:
RocketChatClientFactory
)
{
private
val
client
:
RocketChatClient
=
factory
.
create
(
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
)
{
val
server
=
serverInteractor
.
get
()
if
(
twoFactorAuthenticationCode
.
isBlank
())
{
view
.
alertBlankTwoFactorAuthenticationCode
()
}
else
if
(
server
==
null
)
{
navigator
.
toServerScreen
()
}
else
{
launchUI
(
strategy
)
{
val
client
=
factory
.
create
(
server
)
if
(
NetworkHelper
.
hasInternetAccess
())
{
view
.
showLoading
()
try
{
// The token is saved via the client TokenProvider
client
.
login
(
usernameOrEmail
,
password
,
twoFactorAuthenticationCode
)
registerPushToken
()
navigator
.
toChatList
()
}
catch
(
exception
:
RocketChatException
)
{
if
(
exception
is
RocketChatAuthException
)
{
view
.
alertInvalidTwoFactorAuthenticationCode
()
}
else
{
val
message
=
exception
.
message
if
(
message
!=
null
)
{
view
.
showMessage
(
message
)
when
{
server
==
null
->
{
navigator
.
toServerScreen
()
}
twoFactorAuthenticationCode
.
isBlank
()
->
{
view
.
alertBlankTwoFactorAuthenticationCode
()
}
else
->
{
launchUI
(
strategy
)
{
val
client
=
factory
.
create
(
server
)
if
(
NetworkHelper
.
hasInternetAccess
())
{
view
.
showLoading
()
try
{
// The token is saved via the client TokenProvider
client
.
login
(
usernameOrEmail
,
password
,
twoFactorAuthenticationCode
)
registerPushToken
()
navigator
.
toChatList
()
}
catch
(
exception
:
RocketChatException
)
{
if
(
exception
is
RocketChatAuthException
)
{
view
.
alertInvalidTwoFactorAuthenticationCode
()
}
else
{
view
.
showGenericErrorMessage
()
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
}
finally
{
view
.
hideLoading
()
}
}
else
{
view
.
showNoInternetConnection
()
}
view
.
hideLoading
()
}
else
{
view
.
showNoInternetConnection
()
}
}
}
}
fun
signup
()
{
navigator
.
toSignUp
()
}
fun
signup
()
=
navigator
.
toSignUp
()
private
suspend
fun
registerPushToken
()
{
localRepository
.
get
(
LocalRepository
.
KEY_PUSH_TOKEN
)
?.
let
{
...
...
app/src/main/java/chat/rocket/android/authentication/ui/AuthenticationActivity.kt
View file @
6a1f37b7
...
...
@@ -21,7 +21,7 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
AndroidInjection
.
inject
(
this
)
addFragment
(
"
authentication
ServerFragment"
,
R
.
id
.
fragment_container
)
{
addFragment
(
"ServerFragment"
,
R
.
id
.
fragment_container
)
{
ServerFragment
.
newInstance
()
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/di/ChatRoomFragmentModule.kt
0 → 100644
View file @
6a1f37b7
package
chat.rocket.android.chatroom.di
import
android.arch.lifecycle.LifecycleOwner
import
chat.rocket.android.chatroom.presentation.ChatRoomView
import
chat.rocket.android.chatroom.ui.ChatRoomFragment
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerFragment
import
dagger.Module
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
@PerFragment
class
ChatRoomFragmentModule
{
@Provides
fun
chatRoomView
(
frag
:
ChatRoomFragment
):
ChatRoomView
{
return
frag
}
@Provides
fun
provideLifecycleOwner
(
frag
:
ChatRoomFragment
):
LifecycleOwner
{
return
frag
}
@Provides
fun
provideCancelStrategy
(
owner
:
LifecycleOwner
,
jobs
:
Job
):
CancelStrategy
{
return
CancelStrategy
(
owner
,
jobs
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/di/ChatRoomFragmentProvider.kt
0 → 100644
View file @
6a1f37b7
package
chat.rocket.android.chatroom.di
import
chat.rocket.android.chatroom.ui.ChatRoomFragment
import
dagger.Module
import
dagger.android.ContributesAndroidInjector
@Module
abstract
class
ChatRoomFragmentProvider
{
@ContributesAndroidInjector
(
modules
=
[
ChatRoomFragmentModule
::
class
])
abstract
fun
provideChatRoomFragment
():
ChatRoomFragment
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
0 → 100644
View file @
6a1f37b7
package
chat.rocket.android.chatroom.presentation
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.launchUI
import
chat.rocket.common.model.BaseRoom
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.internal.rest.messages
import
chat.rocket.core.internal.rest.sendMessage
import
javax.inject.Inject
class
ChatRoomPresenter
@Inject
constructor
(
private
val
view
:
ChatRoomView
,
private
val
strategy
:
CancelStrategy
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
factory
:
RocketChatClientFactory
)
{
private
val
client
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
fun
loadMessages
(
chatRoomId
:
String
,
chatRoomType
:
String
,
offset
:
Int
=
0
)
{
launchUI
(
strategy
)
{
view
.
showLoading
()
try
{
val
messages
=
client
.
messages
(
chatRoomId
,
BaseRoom
.
RoomType
.
valueOf
(
chatRoomType
),
offset
.
toLong
(),
30
).
result
view
.
showMessages
(
messages
.
toMutableList
(),
serverInteractor
.
get
()
!!
)
}
catch
(
ex
:
Exception
)
{
ex
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
finally
{
view
.
hideLoading
()
}
}
}
fun
sendMessage
(
chatRoomId
:
String
,
text
:
String
)
{
launchUI
(
strategy
)
{
try
{
val
message
=
client
.
sendMessage
(
chatRoomId
,
text
)
view
.
showSentMessage
(
message
)
}
catch
(
ex
:
Exception
)
{
ex
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt
0 → 100644
View file @
6a1f37b7
package
chat.rocket.android.chatroom.presentation
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.core.model.Message
interface
ChatRoomView
:
LoadingView
,
MessageView
{
/**
* Shows the chat room messages.
*
* @param dataSet The data set to show.
* @param serverUrl The server URL.
*/
fun
showMessages
(
dataSet
:
MutableList
<
Message
>,
serverUrl
:
String
)
/**
* Send a message to a chat room.
*
* @param text The text to send.
*/
fun
sendMessage
(
text
:
String
)
/**
* Shows a (recent) message sent to a chat room.
* @param message The (recent) message sent to a chat room.
*/
fun
showSentMessage
(
message
:
Message
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
0 → 100644
View file @
6a1f37b7
package
chat.rocket.android.chatroom.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
import
chat.rocket.android.R
import
chat.rocket.android.util.addFragment
import
chat.rocket.android.util.textContent
import
dagger.android.AndroidInjection
import
dagger.android.AndroidInjector
import
dagger.android.DispatchingAndroidInjector
import
dagger.android.support.HasSupportFragmentInjector
import
kotlinx.android.synthetic.main.app_bar_chat_room.*
import
javax.inject.Inject
fun
Context
.
chatRoomIntent
(
chatRoomId
:
String
,
chatRoomName
:
String
,
chatRoomType
:
String
,
isChatRoomReadOnly
:
Boolean
):
Intent
{
return
Intent
(
this
,
ChatRoomActivity
::
class
.
java
).
apply
{
putExtra
(
INTENT_CHAT_ROOM_ID
,
chatRoomId
)
putExtra
(
INTENT_CHAT_ROOM_NAME
,
chatRoomName
)
putExtra
(
INTENT_CHAT_ROOM_TYPE
,
chatRoomType
)
putExtra
(
INTENT_IS_CHAT_ROOM_READ_ONLY
,
isChatRoomReadOnly
)
}
}
private
const
val
INTENT_CHAT_ROOM_ID
=
"chat_room_id"
private
const
val
INTENT_CHAT_ROOM_NAME
=
"chat_room_name"
private
const
val
INTENT_CHAT_ROOM_TYPE
=
"chat_room_type"
private
const
val
INTENT_IS_CHAT_ROOM_READ_ONLY
=
"is_chat_room_read_only"
class
ChatRoomActivity
:
AppCompatActivity
(),
HasSupportFragmentInjector
{
@Inject
lateinit
var
fragmentDispatchingAndroidInjector
:
DispatchingAndroidInjector
<
Fragment
>
private
lateinit
var
chatRoomId
:
String
private
lateinit
var
chatRoomName
:
String
private
lateinit
var
chatRoomType
:
String
private
var
isChatRoomReadOnly
:
Boolean
=
false
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
setContentView
(
R
.
layout
.
activity_chat_room
)
AndroidInjection
.
inject
(
this
)
chatRoomId
=
intent
.
getStringExtra
(
INTENT_CHAT_ROOM_ID
)
requireNotNull
(
chatRoomId
)
{
"no chat_room_id provided in Intent extras"
}
chatRoomName
=
intent
.
getStringExtra
(
INTENT_CHAT_ROOM_NAME
)
requireNotNull
(
chatRoomName
)
{
"no chat_room_name provided in Intent extras"
}
chatRoomType
=
intent
.
getStringExtra
(
INTENT_CHAT_ROOM_TYPE
)
requireNotNull
(
chatRoomType
)
{
"no chat_room_type provided in Intent extras"
}
isChatRoomReadOnly
=
intent
.
getBooleanExtra
(
INTENT_IS_CHAT_ROOM_READ_ONLY
,
true
)
requireNotNull
(
chatRoomType
)
{
"no is_chat_room_read_only provided in Intent extras"
}
setupToolbar
(
chatRoomName
)
addFragment
(
"ChatRoomFragment"
,
R
.
id
.
fragment_container
)
{
newInstance
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
isChatRoomReadOnly
)
}
}
override
fun
onBackPressed
()
=
finishActivity
()
override
fun
supportFragmentInjector
():
AndroidInjector
<
Fragment
>
{
return
fragmentDispatchingAndroidInjector
}
private
fun
setupToolbar
(
chatRoomName
:
String
)
{
text_room_name
.
textContent
=
chatRoomName
toolbar
.
setNavigationOnClickListener
{
finishActivity
()
}
}
private
fun
finishActivity
()
{
super
.
onBackPressed
()
overridePendingTransition
(
R
.
anim
.
close_enter
,
R
.
anim
.
close_exit
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomAdapter.kt
0 → 100644
View file @
6a1f37b7
package
chat.rocket.android.chatroom.ui
import
DateTimeHelper
import
android.content.Context
import
android.support.v7.widget.RecyclerView
import
android.view.View
import
android.view.ViewGroup
import
android.widget.ImageView
import
android.widget.TextView
import
chat.rocket.android.R
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.util.inflate
import
chat.rocket.android.util.setVisibility
import
chat.rocket.android.util.textContent
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.model.Message
import
com.facebook.drawee.view.SimpleDraweeView
import
kotlinx.android.synthetic.main.avatar.view.*
import
kotlinx.android.synthetic.main.item_message.view.*
class
ChatRoomAdapter
(
private
val
context
:
Context
,
private
var
dataSet
:
MutableList
<
Message
>,
private
val
serverUrl
:
String
)
:
RecyclerView
.
Adapter
<
ChatRoomAdapter
.
ViewHolder
>()
{
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
ViewHolder
=
ViewHolder
(
parent
.
inflate
(
R
.
layout
.
item_message
))
override
fun
onBindViewHolder
(
holder
:
ViewHolder
,
position
:
Int
)
=
holder
.
bind
(
dataSet
[
position
])
override
fun
getItemCount
():
Int
=
dataSet
.
size
override
fun
getItemViewType
(
position
:
Int
):
Int
=
position
fun
addDataSet
(
dataSet
:
List
<
Message
>)
{
val
previousDataSetSize
=
this
.
dataSet
.
size
this
.
dataSet
.
addAll
(
previousDataSetSize
,
dataSet
)
notifyItemRangeInserted
(
previousDataSetSize
,
dataSet
.
size
)
}
fun
addItem
(
message
:
Message
)
{
dataSet
.
add
(
0
,
message
)
notifyItemInserted
(
0
)
}
inner
class
ViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
fun
bind
(
message
:
Message
)
=
with
(
itemView
)
{
bindUserAvatar
(
message
,
image_avatar
,
image_unknown_avatar
)
bindUserName
(
message
,
text_user_name
)
bindTime
(
message
,
text_message_time
)
bindContent
(
message
,
text_content
)
}
private
fun
bindUserAvatar
(
message
:
Message
,
drawee
:
SimpleDraweeView
,
imageUnknownAvatar
:
ImageView
)
=
message
.
sender
?.
username
.
let
{
drawee
.
setImageURI
(
UrlHelper
.
getAvatarUrl
(
serverUrl
,
it
.
toString
()))
}.
ifNull
{
imageUnknownAvatar
.
setVisibility
(
true
)
}
private
fun
bindUserName
(
message
:
Message
,
textView
:
TextView
)
=
message
.
sender
?.
username
.
let
{
textView
.
textContent
=
it
.
toString
()
}.
ifNull
{
textView
.
textContent
=
context
.
getString
(
R
.
string
.
msg_unknown
)
}
private
fun
bindTime
(
message
:
Message
,
textView
:
TextView
)
{
textView
.
textContent
=
DateTimeHelper
.
getTime
(
DateTimeHelper
.
getLocalDateTime
(
message
.
timestamp
))
}
private
fun
bindContent
(
message
:
Message
,
textView
:
TextView
)
{
textView
.
textContent
=
message
.
message
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
0 → 100644
View file @
6a1f37b7
package
chat.rocket.android.chatroom.ui
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v7.widget.LinearLayoutManager
import
android.support.v7.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
android.widget.Toast
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.presentation.ChatRoomPresenter
import
chat.rocket.android.chatroom.presentation.ChatRoomView
import
chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import
chat.rocket.android.util.inflate
import
chat.rocket.android.util.setVisibility
import
chat.rocket.android.util.textContent
import
chat.rocket.core.model.Message
import
dagger.android.support.AndroidSupportInjection
import
kotlinx.android.synthetic.main.fragment_chat_room.*
import
kotlinx.android.synthetic.main.message_composer.*
import
javax.inject.Inject
fun
newInstance
(
chatRoomId
:
String
,
chatRoomName
:
String
,
chatRoomType
:
String
,
isChatRoomReadOnly
:
Boolean
):
Fragment
{
return
ChatRoomFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
BUNDLE_CHAT_ROOM_ID
,
chatRoomId
)
putString
(
BUNDLE_CHAT_ROOM_NAME
,
chatRoomName
)
putString
(
BUNDLE_CHAT_ROOM_TYPE
,
chatRoomType
)
putBoolean
(
BUNDLE_IS_CHAT_ROOM_READ_ONLY
,
isChatRoomReadOnly
)
}
}
}
private
const
val
BUNDLE_CHAT_ROOM_ID
=
"chat_room_id"
private
const
val
BUNDLE_CHAT_ROOM_NAME
=
"chat_room_name"
private
const
val
BUNDLE_CHAT_ROOM_TYPE
=
"chat_room_type"
private
const
val
BUNDLE_IS_CHAT_ROOM_READ_ONLY
=
"is_chat_room_read_only"
class
ChatRoomFragment
:
Fragment
(),
ChatRoomView
{
@Inject
lateinit
var
presenter
:
ChatRoomPresenter
private
lateinit
var
chatRoomId
:
String
private
lateinit
var
chatRoomName
:
String
private
lateinit
var
chatRoomType
:
String
private
var
isChatRoomReadOnly
:
Boolean
=
false
private
lateinit
var
adapter
:
ChatRoomAdapter
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
chatRoomName
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_NAME
)
chatRoomType
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_TYPE
)
isChatRoomReadOnly
=
bundle
.
getBoolean
(
BUNDLE_IS_CHAT_ROOM_READ_ONLY
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
container
?.
inflate
(
R
.
layout
.
fragment_chat_room
)
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
presenter
.
loadMessages
(
chatRoomId
,
chatRoomType
)
setupComposer
()
}
override
fun
showMessages
(
dataSet
:
MutableList
<
Message
>,
serverUrl
:
String
)
{
activity
?.
apply
{
if
(
recycler_view
.
adapter
==
null
)
{
adapter
=
ChatRoomAdapter
(
this
,
dataSet
,
serverUrl
)
recycler_view
.
adapter
=
adapter
val
linearLayoutManager
=
LinearLayoutManager
(
context
,
LinearLayoutManager
.
VERTICAL
,
true
)
recycler_view
.
layoutManager
=
linearLayoutManager
if
(
dataSet
.
size
>=
30
)
{
recycler_view
.
addOnScrollListener
(
object
:
EndlessRecyclerViewScrollListener
(
linearLayoutManager
)
{
override
fun
onLoadMore
(
page
:
Int
,
totalItemsCount
:
Int
,
recyclerView
:
RecyclerView
?)
{
presenter
.
loadMessages
(
chatRoomId
,
chatRoomType
,
page
*
30
)
}
})
}
}
else
{
adapter
.
addDataSet
(
dataSet
)
}
}
}
override
fun
sendMessage
(
text
:
String
)
{
if
(!
text
.
isBlank
())
{
presenter
.
sendMessage
(
chatRoomId
,
text
)
}
}
override
fun
showSentMessage
(
message
:
Message
)
{
text_message
.
textContent
=
""
adapter
.
addItem
(
message
)
recycler_view
.
smoothScrollToPosition
(
0
)
}
override
fun
showLoading
()
=
view_loading
.
setVisibility
(
true
)
override
fun
hideLoading
()
=
view_loading
.
setVisibility
(
false
)
override
fun
showMessage
(
message
:
String
)
=
Toast
.
makeText
(
activity
,
message
,
Toast
.
LENGTH_SHORT
).
show
()
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
private
fun
setupComposer
()
{
if
(
isChatRoomReadOnly
)
{
text_room_is_read_only
.
setVisibility
(
true
)
top_container
.
setVisibility
(
false
)
}
else
{
text_send
.
setOnClickListener
{
sendMessage
(
text_message
.
textContent
)
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/di/ChatRoomsFragmentModule.kt
View file @
6a1f37b7
...
...
@@ -27,9 +27,4 @@ class ChatRoomsFragmentModule {
fun
provideCancelStrategy
(
owner
:
LifecycleOwner
,
jobs
:
Job
):
CancelStrategy
{
return
CancelStrategy
(
owner
,
jobs
)
}
@Provides
fun
provideJob
():
Job
{
return
Job
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/di/ChatRoomsModule.kt
0 → 100644
View file @
6a1f37b7
package
chat.rocket.android.chatrooms.di
import
android.content.Context
import
chat.rocket.android.chatrooms.presentation.ChatRoomsNavigator
import
chat.rocket.android.chatrooms.ui.MainActivity
import
chat.rocket.android.dagger.scope.PerActivity
import
dagger.Module
import
dagger.Provides
@Module
class
ChatRoomsModule
{
@Provides
@PerActivity
fun
provideAuthenticationNavigator
(
activity
:
MainActivity
,
context
:
Context
)
=
ChatRoomsNavigator
(
activity
,
context
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsNavigator.kt
0 → 100644
View file @
6a1f37b7
package
chat.rocket.android.chatrooms.presentation
import
android.content.Context
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.ui.chatRoomIntent
import
chat.rocket.android.chatrooms.ui.MainActivity
class
ChatRoomsNavigator
(
private
val
activity
:
MainActivity
,
private
val
context
:
Context
)
{
fun
toChatRoom
(
chatRoomId
:
String
,
chatRoomName
:
String
,
chatRoomType
:
String
,
isChatRoomReadOnly
:
Boolean
)
{
activity
.
startActivity
(
context
.
chatRoomIntent
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
isChatRoomReadOnly
))
activity
.
overridePendingTransition
(
R
.
anim
.
open_enter
,
R
.
anim
.
open_exit
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
6a1f37b7
...
...
@@ -18,11 +18,11 @@ import javax.inject.Inject
class
ChatRoomsPresenter
@Inject
constructor
(
private
val
view
:
ChatRoomsView
,
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
ChatRoomsNavigator
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
getChatRoomsInteractor
:
GetChatRoomsInteractor
,
private
val
saveChatRoomsInteractor
:
SaveChatRoomsInteractor
,
factory
:
RocketChatClientFactory
)
{
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
var
reloadJob
:
Deferred
<
List
<
ChatRoom
>>?
=
null
...
...
@@ -36,6 +36,20 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
}
fun
loadChatRoom
(
chatRoom
:
ChatRoom
)
=
navigator
.
toChatRoom
(
chatRoom
.
id
,
chatRoom
.
name
,
chatRoom
.
type
.
name
,
chatRoom
.
readonly
?:
false
)
/**
* Gets a [ChatRoom] list from local repository.
* ChatRooms returned are filtered by name.
*/
fun
chatRoomsByName
(
name
:
String
)
{
val
currentServer
=
serverInteractor
.
get
()
!!
launchUI
(
strategy
)
{
val
roomList
=
getChatRoomsInteractor
.
getByName
(
currentServer
,
name
)
view
.
updateChatRooms
(
roomList
)
}
}
private
suspend
fun
loadRooms
():
List
<
ChatRoom
>
{
val
chatRooms
=
client
.
chatRooms
().
update
val
sortedRooms
=
sortRooms
(
chatRooms
)
...
...
@@ -54,24 +68,13 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
}
/**
* Get a ChatRoom list from local repository. ChatRooms returned are filtered by name.
*/
fun
chatRoomsByName
(
name
:
String
)
{
val
currentServer
=
serverInteractor
.
get
()
!!
launchUI
(
strategy
)
{
val
roomList
=
getChatRoomsInteractor
.
getByName
(
currentServer
,
name
)
view
.
updateChatRooms
(
roomList
)
}
}
private
fun
getOpenChatRooms
(
chatRooms
:
List
<
ChatRoom
>):
List
<
ChatRoom
>
{
return
chatRooms
.
filter
(
ChatRoom
::
open
)
}
private
fun
sortChatRooms
(
chatRooms
:
List
<
ChatRoom
>):
List
<
ChatRoom
>
{
return
chatRooms
.
sortedByDescending
{
chatRoom
->
chatRoom
.
lastMessage
?.
timestamp
return
chatRooms
.
sortedByDescending
{
chatRoom
->
chatRoom
.
lastMessage
?.
timestamp
}
}
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsAdapter.kt
View file @
6a1f37b7
...
...
@@ -16,83 +16,96 @@ import chat.rocket.android.util.textContent
import
chat.rocket.common.model.BaseRoom.RoomType
import
chat.rocket.core.model.ChatRoom
import
com.facebook.drawee.view.SimpleDraweeView
import
kotlinx.android.synthetic.main.avatar.view.*
import
kotlinx.android.synthetic.main.item_chat.view.*
class
ChatRoomsAdapter
(
private
val
context
:
Context
)
:
RecyclerView
.
Adapter
<
ChatRoomsAdapter
.
ViewHolder
>()
{
class
ChatRoomsAdapter
(
private
val
context
:
Context
,
private
val
listener
:
(
ChatRoom
)
->
Unit
)
:
RecyclerView
.
Adapter
<
ChatRoomsAdapter
.
ViewHolder
>()
{
var
dataSet
:
MutableList
<
ChatRoom
>
=
ArrayList
()
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
ViewHolder
=
ViewHolder
(
parent
.
inflate
(
R
.
layout
.
item_chat
))
override
fun
onBindViewHolder
(
holder
:
ViewHolder
,
position
:
Int
)
=
holder
.
bind
(
dataSet
[
position
])
override
fun
getItemCount
():
Int
=
dataSet
.
size
override
fun
getItemViewType
(
position
:
Int
):
Int
=
position
fun
updateRooms
(
newRooms
:
List
<
ChatRoom
>)
{
dataSet
.
clear
()
dataSet
.
addAll
(
newRooms
)
}
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
ViewHolder
=
ViewHolder
(
parent
.
inflate
(
R
.
layout
.
item_chat
))
override
fun
onBindViewHolder
(
holder
:
ViewHolder
,
position
:
Int
)
{
val
chatRoom
=
dataSet
[
position
]
val
chatRoomName
=
chatRoom
.
name
inner
class
ViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
holder
.
chatName
.
textContent
=
chatRoomName
fun
bind
(
chatRoom
:
ChatRoom
)
=
with
(
itemView
)
{
bindAvatar
(
chatRoom
,
layout_avatar
,
image_avatar
,
image_room_avatar
)
bindName
(
chatRoom
,
text_chat_name
)
bindLastMessageDateTime
(
chatRoom
,
text_last_message_date_time
)
bindLastMessage
(
chatRoom
,
text_last_message
)
bindUnreadMessages
(
chatRoom
,
text_total_unread_messages
)
if
(
chatRoom
.
type
==
RoomType
.
ONE_TO_ONE
)
{
// TODO Check the best way to get the current server url.
val
canonicalUrl
=
chatRoom
.
client
.
url
holder
.
userAvatar
.
setImageURI
(
UrlHelper
.
getAvatarUrl
(
canonicalUrl
,
chatRoomName
))
holder
.
userAvatar
.
setVisibility
(
true
)
}
else
{
holder
.
roomAvatar
.
setImageDrawable
(
DrawableHelper
.
getTextDrawable
(
chatRoomName
))
holder
.
roomAvatar
.
setVisibility
(
true
)
setOnClickListener
{
listener
(
chatRoom
)
}
}
val
totalUnreadMessage
=
chatRoom
.
unread
when
{
totalUnreadMessage
in
1
..
99
->
{
holder
.
unreadMessage
.
textContent
=
totalUnreadMessage
.
toString
()
holder
.
unreadMessage
.
setVisibility
(
true
)
private
fun
bindAvatar
(
chatRoom
:
ChatRoom
,
avatarLayout
:
View
,
drawee
:
SimpleDraweeView
,
imageView
:
ImageView
)
{
val
chatRoomName
=
chatRoom
.
name
if
(
chatRoom
.
type
==
RoomType
.
ONE_TO_ONE
)
{
drawee
.
setImageURI
(
UrlHelper
.
getAvatarUrl
(
chatRoom
.
client
.
url
,
chatRoomName
))
imageView
.
setVisibility
(
false
)
avatarLayout
.
setVisibility
(
true
)
}
else
{
imageView
.
setImageDrawable
(
DrawableHelper
.
getTextDrawable
(
chatRoomName
))
avatarLayout
.
setVisibility
(
false
)
imageView
.
setVisibility
(
true
)
}
totalUnreadMessage
>
99
->
{
holder
.
unreadMessage
.
textContent
=
context
.
getString
(
R
.
string
.
msg_more_than_ninety_nine_unread_messages
)
holder
.
unreadMessage
.
setVisibility
(
true
)
}
private
fun
bindName
(
chatRoom
:
ChatRoom
,
textView
:
TextView
)
{
textView
.
textContent
=
chatRoom
.
name
}
private
fun
bindLastMessageDateTime
(
chatRoom
:
ChatRoom
,
textView
:
TextView
)
{
val
lastMessage
=
chatRoom
.
lastMessage
if
(
lastMessage
!=
null
)
{
val
localDateTime
=
DateTimeHelper
.
getLocalDateTime
(
lastMessage
.
timestamp
)
textView
.
textContent
=
DateTimeHelper
.
getDate
(
localDateTime
,
context
)
}
}
val
lastMessage
=
chatRoom
.
lastMessage
val
lastMessageSender
=
lastMessage
?.
sender
if
(
lastMessage
!=
null
&&
lastMessageSender
!=
null
)
{
val
message
=
lastMessage
.
message
val
senderUsername
=
lastMessageSender
.
username
when
(
senderUsername
)
{
chatRoomName
->
{
holder
.
lastMessage
.
textContent
=
message
}
private
fun
bindLastMessage
(
chatRoom
:
ChatRoom
,
textView
:
TextView
)
{
val
lastMessage
=
chatRoom
.
lastMessage
val
lastMessageSender
=
lastMessage
?.
sender
if
(
lastMessage
!=
null
&&
lastMessageSender
!=
null
)
{
val
message
=
lastMessage
.
message
val
senderUsername
=
lastMessageSender
.
username
when
(
senderUsername
)
{
chatRoom
.
name
->
{
textView
.
textContent
=
message
}
// TODO Change to MySelf
// chatRoom.user?.username -> {
// holder.lastMessage.textContent = context.getString(R.string.msg_you) + ": $message"
// }
else
->
{
holder
.
lastMessage
.
textContent
=
"@$senderUsername: $message"
// chatRoom.user?.username -> {
// holder.lastMessage.textContent = context.getString(R.string.msg_you) + ": $message"
// }
else
->
{
textView
.
textContent
=
"@$senderUsername: $message"
}
}
}
val
localDateTime
=
DateTimeHelper
.
getLocalDateTime
(
lastMessage
.
timestamp
)
holder
.
lastMessageDateTime
.
textContent
=
DateTimeHelper
.
getDate
(
localDateTime
,
context
)
}
}
override
fun
onBindViewHolder
(
holder
:
ViewHolder
,
position
:
Int
,
payloads
:
MutableList
<
Any
>?)
{
onBindViewHolder
(
holder
,
position
)
}
override
fun
getItemCount
():
Int
=
dataSet
.
size
override
fun
getItemViewType
(
position
:
Int
):
Int
=
position
class
ViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
val
userAvatar
:
SimpleDraweeView
=
itemView
.
image_user_avatar
val
roomAvatar
:
ImageView
=
itemView
.
image_room_avatar
val
chatName
:
TextView
=
itemView
.
text_chat_name
val
lastMessage
:
TextView
=
itemView
.
text_last_message
val
lastMessageDateTime
:
TextView
=
itemView
.
text_last_message_date_time
val
unreadMessage
:
TextView
=
itemView
.
text_total_unread_messages
private
fun
bindUnreadMessages
(
chatRoom
:
ChatRoom
,
textView
:
TextView
)
{
val
totalUnreadMessage
=
chatRoom
.
unread
when
{
totalUnreadMessage
in
1
..
99
->
{
textView
.
textContent
=
totalUnreadMessage
.
toString
()
textView
.
setVisibility
(
true
)
}
totalUnreadMessage
>
99
->
{
textView
.
textContent
=
context
.
getString
(
R
.
string
.
msg_more_than_ninety_nine_unread_messages
)
textView
.
setVisibility
(
true
)
}
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
6a1f37b7
...
...
@@ -12,6 +12,7 @@ import android.widget.Toast
import
chat.rocket.android.R
import
chat.rocket.android.chatrooms.presentation.ChatRoomsPresenter
import
chat.rocket.android.chatrooms.presentation.ChatRoomsView
import
chat.rocket.android.util.setVisibility
import
chat.rocket.android.widget.DividerItemDecoration
import
chat.rocket.core.model.ChatRoom
import
dagger.android.support.AndroidSupportInjection
...
...
@@ -46,8 +47,11 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
(
activity
as
AppCompatActivity
).
apply
{
recycler_view
.
layoutManager
=
LinearLayoutManager
(
this
,
LinearLayoutManager
.
VERTICAL
,
false
)
recycler_view
.
addItemDecoration
(
DividerItemDecoration
(
this
,
144
,
32
))
recycler_view
.
adapter
=
ChatRoomsAdapter
(
this
)
recycler_view
.
itemAnimator
=
DefaultItemAnimator
()
recycler_view
.
adapter
=
ChatRoomsAdapter
(
this
)
{
chatRoom
->
presenter
.
loadChatRoom
(
chatRoom
)
}
if
(
supportActionBar
==
null
)
{
setSupportActionBar
(
toolbar
)
supportActionBar
?.
setDisplayHomeAsUpEnabled
(
false
)
...
...
@@ -57,6 +61,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
supportActionBar
?.
title
=
"Rocket.Chat"
}
}
presenter
.
loadChatRooms
()
}
...
...
@@ -97,9 +102,9 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
}
}
override
fun
showLoading
()
=
view_loading
.
s
how
(
)
override
fun
showLoading
()
=
view_loading
.
s
etVisibility
(
true
)
override
fun
hideLoading
()
=
view_loading
.
hide
(
)
override
fun
hideLoading
()
=
view_loading
.
setVisibility
(
false
)
override
fun
showMessage
(
message
:
String
)
=
Toast
.
makeText
(
activity
,
message
,
Toast
.
LENGTH_SHORT
).
show
()
...
...
@@ -112,6 +117,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
class
RoomsDiffCallback
(
private
val
oldRooms
:
List
<
ChatRoom
>,
private
val
newRooms
:
List
<
ChatRoom
>)
:
DiffUtil
.
Callback
()
{
override
fun
areItemsTheSame
(
oldItemPosition
:
Int
,
newItemPosition
:
Int
):
Boolean
{
return
oldRooms
[
oldItemPosition
].
id
==
newRooms
[
newItemPosition
].
id
}
...
...
app/src/main/java/chat/rocket/android/dagger/module/ActivityBuilder.kt
View file @
6a1f37b7
...
...
@@ -6,7 +6,10 @@ import chat.rocket.android.authentication.server.di.ServerFragmentProvider
import
chat.rocket.android.authentication.signup.di.SignupFragmentProvider
import
chat.rocket.android.authentication.twofactor.di.TwoFAFragmentProvider
import
chat.rocket.android.authentication.ui.AuthenticationActivity
import
chat.rocket.android.chatroom.di.ChatRoomFragmentProvider
import
chat.rocket.android.chatroom.ui.ChatRoomActivity
import
chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider
import
chat.rocket.android.chatrooms.di.ChatRoomsModule
import
chat.rocket.android.chatrooms.ui.MainActivity
import
chat.rocket.android.dagger.scope.PerActivity
import
dagger.Module
...
...
@@ -24,6 +27,11 @@ abstract class ActivityBuilder {
])
abstract
fun
bindAuthenticationActivity
():
AuthenticationActivity
@ContributesAndroidInjector
(
modules
=
[
ChatRoomsFragmentProvider
::
class
])
@PerActivity
@ContributesAndroidInjector
(
modules
=
[
ChatRoomsModule
::
class
,
ChatRoomsFragmentProvider
::
class
])
abstract
fun
bindMainActivity
():
MainActivity
@PerActivity
@ContributesAndroidInjector
(
modules
=
[
ChatRoomFragmentProvider
::
class
])
abstract
fun
bindChatRoomActivity
():
ChatRoomActivity
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt
View file @
6a1f37b7
...
...
@@ -21,6 +21,7 @@ import chat.rocket.common.util.PlatformLogger
import
chat.rocket.core.RocketChatClient
import
dagger.Module
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
import
okhttp3.OkHttpClient
import
okhttp3.logging.HttpLoggingInterceptor
import
javax.inject.Singleton
...
...
@@ -47,6 +48,11 @@ class AppModule {
return
Room
.
databaseBuilder
(
context
,
RocketChatDatabase
::
class
.
java
,
"rocketchat-db"
).
build
()
}
@Provides
fun
provideJob
():
Job
{
return
Job
()
}
@Provides
@Singleton
fun
provideContext
(
application
:
Application
):
Context
{
...
...
@@ -120,4 +126,4 @@ class AppModule {
fun
provideChatRoomsRepository
():
ChatRoomsRepository
{
return
MemoryChatRoomsRepository
()
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/helper/EndlessRecyclerViewScrollListener.kt
0 → 100644
View file @
6a1f37b7
package
chat.rocket.android.helper
import
android.support.v7.widget.GridLayoutManager
import
android.support.v7.widget.LinearLayoutManager
import
android.support.v7.widget.RecyclerView
import
android.support.v7.widget.StaggeredGridLayoutManager
/**
* Info: https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews-and-RecyclerView
*/
abstract
class
EndlessRecyclerViewScrollListener
:
RecyclerView
.
OnScrollListener
{
private
var
visibleThreshold
=
5
// The minimum amount of items to have below of the current scroll position before loading more.
private
var
currentPage
=
0
// The current offset index of data loaded
private
var
previousTotalItemCount
=
0
// The total number of items in the dataset after the last load
private
var
loading
=
true
// True if we are still waiting for the last set of data to load.
private
val
startingPageIndex
=
0
// Sets the starting page index
private
var
layoutManager
:
RecyclerView
.
LayoutManager
constructor
(
layoutManager
:
LinearLayoutManager
)
{
this
.
layoutManager
=
layoutManager
}
constructor
(
layoutManager
:
GridLayoutManager
)
{
this
.
layoutManager
=
layoutManager
visibleThreshold
*=
layoutManager
.
spanCount
}
constructor
(
layoutManager
:
StaggeredGridLayoutManager
)
{
this
.
layoutManager
=
layoutManager
visibleThreshold
*=
layoutManager
.
spanCount
}
private
fun
getLastVisibleItem
(
lastVisibleItemPositions
:
IntArray
):
Int
{
var
maxSize
=
0
for
(
i
in
lastVisibleItemPositions
.
indices
)
{
if
(
i
==
0
)
{
maxSize
=
lastVisibleItemPositions
[
i
]
}
else
if
(
lastVisibleItemPositions
[
i
]
>
maxSize
)
{
maxSize
=
lastVisibleItemPositions
[
i
]
}
}
return
maxSize
}
// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
override
fun
onScrolled
(
view
:
RecyclerView
?,
dx
:
Int
,
dy
:
Int
)
{
var
lastVisibleItemPosition
=
0
val
totalItemCount
=
layoutManager
.
itemCount
when
(
layoutManager
)
{
is
StaggeredGridLayoutManager
->
{
val
lastVisibleItemPositions
=
(
layoutManager
as
StaggeredGridLayoutManager
).
findLastVisibleItemPositions
(
null
)
// get maximum element within the list
lastVisibleItemPosition
=
getLastVisibleItem
(
lastVisibleItemPositions
)
}
is
GridLayoutManager
->
lastVisibleItemPosition
=
(
layoutManager
as
GridLayoutManager
).
findLastVisibleItemPosition
()
is
LinearLayoutManager
->
lastVisibleItemPosition
=
(
layoutManager
as
LinearLayoutManager
).
findLastVisibleItemPosition
()
}
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
// If it isn’t currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to fetch the data.
// threshold should reflect how many total columns there are too
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if
(
totalItemCount
<
previousTotalItemCount
)
{
this
.
currentPage
=
this
.
startingPageIndex
this
.
previousTotalItemCount
=
totalItemCount
if
(
totalItemCount
==
0
)
{
this
.
loading
=
true
}
}
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
if
(
loading
&&
totalItemCount
>
previousTotalItemCount
)
{
loading
=
false
previousTotalItemCount
=
totalItemCount
}
// If it isn’t currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to fetch the data.
// threshold should reflect how many total columns there are too
if
(!
loading
&&
lastVisibleItemPosition
+
visibleThreshold
>
totalItemCount
)
{
currentPage
++
onLoadMore
(
currentPage
,
totalItemCount
,
view
)
loading
=
true
}
}
// Call this method whenever performing new searches
fun
resetState
()
{
this
.
currentPage
=
this
.
startingPageIndex
this
.
previousTotalItemCount
=
0
this
.
loading
=
true
}
// Defines the process for actually loading more data based on page
abstract
fun
onLoadMore
(
page
:
Int
,
totalItemsCount
:
Int
,
recyclerView
:
RecyclerView
?)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
View file @
6a1f37b7
package
chat.rocket.android.helper
import
android.util.Patterns
object
UrlHelper
{
/**
* Returns the avatar URL.
*
* @param serverUrl The server
Url
.
* @param
chatRoomName The chat room
name.
* @param serverUrl The server
URL
.
* @param
avatarName The avatar
name.
* @return The avatar URL.
*/
fun
getAvatarUrl
(
serverUrl
:
String
,
chatRoomName
:
String
):
String
=
serverUrl
+
"avatar/"
+
chatRoomName
fun
getAvatarUrl
(
serverUrl
:
String
,
avatarName
:
String
):
String
=
removeTrailingSlash
(
serverUrl
)
+
"/avatar/"
+
avatarName
/**
* 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/server/domain/ChatRoomsRepository.kt
View file @
6a1f37b7
...
...
@@ -3,6 +3,8 @@ package chat.rocket.android.server.domain
import
chat.rocket.core.model.ChatRoom
interface
ChatRoomsRepository
{
fun
save
(
url
:
String
,
chatRooms
:
List
<
ChatRoom
>)
fun
get
(
url
:
String
):
List
<
ChatRoom
>
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/SaveChatRoomsInteractor.kt
View file @
6a1f37b7
...
...
@@ -4,5 +4,6 @@ import chat.rocket.core.model.ChatRoom
import
javax.inject.Inject
class
SaveChatRoomsInteractor
@Inject
constructor
(
private
val
repository
:
ChatRoomsRepository
)
{
fun
save
(
url
:
String
,
chatRooms
:
List
<
ChatRoom
>)
=
repository
.
save
(
url
,
chatRooms
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/SaveSettingsInteractor.kt
View file @
6a1f37b7
...
...
@@ -4,5 +4,6 @@ import chat.rocket.core.model.Value
import
javax.inject.Inject
class
SaveSettingsInteractor
@Inject
constructor
(
private
val
repository
:
SettingsRepository
)
{
fun
save
(
url
:
String
,
settings
:
Map
<
String
,
Value
<
Any
>>)
=
repository
.
save
(
url
,
settings
)
}
\ No newline at end of file
app/src/main/res/anim/accelerate_cubic.xml
0 → 100644
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<accelerateInterpolator
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:factor=
"1.5"
/>
\ No newline at end of file
app/src/main/res/anim/close_enter.xml
0 → 100644
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:background=
"@android:color/black"
android:fillAfter=
"true"
android:fillBefore=
"true"
android:fillEnabled=
"true"
android:shareInterpolator=
"false"
android:zAdjustment=
"top"
>
<alpha
android:duration=
"250"
android:fromAlpha=
"0.2"
android:interpolator=
"@anim/accelerate_cubic"
android:toAlpha=
"1.0"
/>
<scale
android:duration=
"250"
android:fromXScale=
"0.9"
android:fromYScale=
"0.9"
android:interpolator=
"@anim/accelerate_cubic"
android:pivotX=
"50.0%p"
android:pivotY=
"50.0%p"
android:toXScale=
"1.0"
android:toYScale=
"1.0"
/>
</set>
\ No newline at end of file
app/src/main/res/anim/close_exit.xml
0 → 100644
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:zAdjustment=
"top"
>
<translate
android:duration=
"250"
android:fromXDelta=
"0.0%p"
android:interpolator=
"@anim/accelerate_cubic"
android:toXDelta=
"100.0%p"
/>
</set>
\ No newline at end of file
app/src/main/res/anim/decelerate_cubic.xml
0 → 100644
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<decelerateInterpolator
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:factor=
"1.5"
/>
\ No newline at end of file
app/src/main/res/anim/open_enter.xml
0 → 100644
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:zAdjustment=
"top"
>
<translate
android:duration=
"250"
android:fromXDelta=
"100.0%p"
android:interpolator=
"@anim/decelerate_cubic"
android:toXDelta=
"0.0%p"
/>
</set>
\ No newline at end of file
app/src/main/res/anim/open_exit.xml
0 → 100644
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:background=
"@android:color/black"
android:fillAfter=
"true"
android:fillBefore=
"false"
android:fillEnabled=
"true"
android:shareInterpolator=
"false"
android:zAdjustment=
"normal"
>
<alpha
android:duration=
"250"
android:fromAlpha=
"1.0"
android:interpolator=
"@anim/decelerate_cubic"
android:toAlpha=
"0.2"
/>
<scale
android:duration=
"250"
android:fromXScale=
"1.0"
android:fromYScale=
"1.0"
android:interpolator=
"@anim/decelerate_cubic"
android:pivotX=
"50.0%p"
android:pivotY=
"50.0%p"
android:toXScale=
"0.9"
android:toYScale=
"0.9"
/>
</set>
\ No newline at end of file
app/src/main/res/drawable/ic_help_black_24dp.xml
0 → 100644
View file @
6a1f37b7
<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=
"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"
/>
</vector>
app/src/main/res/layout/activity_authentication.xml
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:theme=
"@style/AuthenticationTheme"
>
android:theme=
"@style/AuthenticationTheme"
tools:context=
".authentication.ui.AuthenticationActivity"
>
<FrameLayout
android:id=
"@+id/fragment_container"
...
...
app/src/main/res/layout/activity_chat_room.xml
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:theme=
"@style/AppTheme"
>
android:theme=
"@style/AppTheme"
tools:context=
".chatroom.ui.ChatRoomActivity"
>
<include
android:id=
"@+id/layout_app_bar"
layout=
"@layout/app_bar"
/>
layout=
"@layout/app_bar
_chat_room
"
/>
<FrameLayout
android:id=
"@+id/fragment_container"
...
...
app/src/main/res/layout/activity_main.xml
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:theme=
"@style/ChatListTheme"
>
android:theme=
"@style/ChatListTheme"
tools:context=
".chatrooms.ui.MainActivity"
>
<FrameLayout
android:id=
"@+id/fragment_container"
...
...
app/src/main/res/layout/app_bar_chat_room.xml
0 → 100644
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
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=
"@color/colorPrimary"
android:theme=
"@style/Theme.AppCompat.Light.NoActionBar"
>
<android.support.v7.widget.Toolbar
android:id=
"@+id/toolbar"
android:layout_width=
"match_parent"
android:layout_height=
"?attr/actionBarSize"
app:layout_scrollFlags=
"scroll|enterAlways"
app:navigationIcon=
"?android:attr/homeAsUpIndicator"
app:popupTheme=
"@style/ThemeOverlay.AppCompat.Light"
app:theme=
"@style/ThemeOverlay.AppCompat.Dark.ActionBar"
>
<android.support.constraint.ConstraintLayout
android:id=
"@+id/toolbar_content_container"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:orientation=
"horizontal"
>
<!-- TODO implement -->
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_room_avatar"
android:layout_width=
"30dp"
android:layout_height=
"30dp"
android:visibility=
"gone"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:roundAsCircle=
"true"
/>
<TextView
android:id=
"@+id/text_room_name"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"10dp"
android:ellipsize=
"end"
android:maxLines=
"1"
android:textColor=
"@color/white"
android:textSize=
"18sp"
android:textStyle=
"bold"
tools:text=
"Developers"
/>
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
\ No newline at end of file
app/src/main/res/layout/avatar.xml
0 → 100644
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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=
"match_parent"
android:orientation=
"vertical"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_avatar"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
app:roundedCornerRadius=
"2dp"
/>
<!-- TODO define the correct bg color for this-->
<ImageView
android:id=
"@+id/image_unknown_avatar"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
android:src=
"@drawable/ic_help_black_24dp"
android:tint=
"@color/colorAccent"
android:visibility=
"gone"
tools:ignore=
"contentDescription"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/fragment_authentication_server.xml
View file @
6a1f37b7
...
...
@@ -32,6 +32,7 @@
android:cursorVisible=
"false"
android:hint=
"@string/default_server"
android:imeOptions=
"actionDone"
android:digits=
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-/"
android:inputType=
"textUri"
android:paddingEnd=
"0dp"
android:paddingStart=
"0dp"
/>
...
...
app/src/main/res/layout/fragment_
message
.xml
→
app/src/main/res/layout/fragment_
chat_room
.xml
View file @
6a1f37b7
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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=
"match_parent"
android:orientation=
"vertical"
>
...
...
@@ -18,4 +20,14 @@
android:layout_height=
"wrap_content"
android:layout_alignParentBottom=
"true"
/>
<com.wang.avi.AVLoadingIndicatorView
android:id=
"@+id/view_loading"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_centerInParent=
"true"
android:visibility=
"gone"
app:indicatorColor=
"@color/black"
app:indicatorName=
"BallPulseIndicator"
tools:visibility=
"visible"
/>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/layout/item_chat.xml
View file @
6a1f37b7
...
...
@@ -18,13 +18,17 @@
app:layout_constraintRight_toLeftOf=
"@+id/middle_container"
app:layout_constraintTop_toTopOf=
"parent"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_user_avatar"
<include
android:id=
"@+id/layout_avatar"
layout=
"@layout/avatar"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
android:visibility=
"gone"
app:roundAsCircle=
"true"
/>
android:visibility=
"gone"
/>
<!-- We need to build the avatar with initials since the server returns a SVG file with a pre defined 50x50 pixel.
TODO: check to scale the SVG file on the app and remove the view bellow (or make the server to return a jpg file.
SVG scaling with fresco is impossible: http://frescolib.org/docs/resizing.html
-->
<ImageView
android:id=
"@+id/image_room_avatar"
android:layout_width=
"40dp"
...
...
app/src/main/res/layout/item_message.xml
View file @
6a1f37b7
...
...
@@ -4,18 +4,19 @@
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"1
6
dp"
android:layout_marginBottom=
"1
0
dp"
android:layout_marginEnd=
"@dimen/screen_edge_left_and_right_margins"
android:layout_marginStart=
"@dimen/screen_edge_left_and_right_margins"
android:layout_marginTop=
"1
6
dp"
>
android:layout_marginTop=
"1
0
dp"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_user_avatar"
<include
android:id=
"@+id/layout_avatar"
layout=
"@layout/avatar"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
android:layout_marginTop=
"7dp"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:roundAsCircle=
"true"
/>
app:layout_constraintTop_toTopOf=
"parent"
/>
<LinearLayout
android:id=
"@+id/top_container"
...
...
@@ -23,7 +24,7 @@
android:layout_height=
"wrap_content"
android:layout_marginStart=
"16dp"
android:orientation=
"horizontal"
app:layout_constraintLeft_toRightOf=
"@+id/
image_user
_avatar"
>
app:layout_constraintLeft_toRightOf=
"@+id/
layout
_avatar"
>
<TextView
android:id=
"@+id/text_user_name"
...
...
@@ -54,11 +55,13 @@
app:layout_constraintTop_toBottomOf=
"@+id/top_container"
tools:text=
"This is a multiline chat message from Bertie that will take more than just one line of text. I have sure that everything is amazing!"
/>
<!-- TODO implement -->
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_attachment"
android:layout_width=
"0dp"
android:layout_height=
"150dp"
android:layout_marginTop=
"5dp"
android:visibility=
"gone"
app:layout_constraintLeft_toLeftOf=
"@id/top_container"
app:layout_constraintRight_toRightOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/text_content"
/>
...
...
app/src/main/res/layout/message_composer.xml
View file @
6a1f37b7
...
...
@@ -10,6 +10,17 @@
android:layout_height=
"1dp"
android:background=
"@color/colorDividerMessageComposer"
/>
<TextView
android:id=
"@+id/text_room_is_read_only"
android:layout_width=
"match_parent"
android:layout_height=
"45dp"
android:background=
"@color/white"
android:gravity=
"center"
android:text=
"@string/msg_this_room_is_read_only"
android:textColor=
"@color/black"
android:visibility=
"gone"
app:layout_constraintTop_toBottomOf=
"@+id/divider"
/>
<LinearLayout
android:id=
"@+id/top_container"
android:layout_width=
"match_parent"
...
...
app/src/main/res/values-pt-rBR/strings.xml
View file @
6a1f37b7
...
...
@@ -11,9 +11,11 @@
<string
name=
"action_send"
>
Enviar
</string>
<string
name=
"action_terms_of_service"
>
Termos de Serviço
</string>
<string
name=
"action_privacy_policy"
>
Política de Privacidade
</string>
<string
name=
"search"
>
Pesquisar
</string>
<!-- Regular information messages -->
<string
name=
"msg_no_internet_connection"
>
Sem conexão à internet
</string>
<string
name=
"msg_invalid_server_url"
>
URL de servidor inválida
</string>
<string
name=
"msg_generic_error"
>
Desculpe, ocorreu um erro, tente novamente
</string>
<string
name=
"msg_username"
>
nome de usuário
</string>
<string
name=
"msg_username_or_email"
>
nome de usuário ou email
</string>
...
...
@@ -21,12 +23,13 @@
<string
name=
"msg_name_and_surname"
>
nome e sobrenome
</string>
<string
name=
"msg_email"
>
email
</string>
<string
name=
"msg_or_continue_using_social_accounts"
>
Ou continue através de contas sociais
</string>
<string
name=
"msg_new_
to_rocket_chat"
>
Novo no Rocket Chat
? %1$s
</string>
<string
name=
"msg_new_
user"
>
Novo usuário
? %1$s
</string>
<string
name=
"msg_new_user_agreement"
>
Ao proceder você concorda com nossos %1$s e %2$s
</string>
<string
name=
"msg_2fa_code"
>
Código 2FA
</string>
<string
name=
"msg_invalid_2fa_code"
>
Código 2FA inválido
</string>
<string
name=
"msg_yesterday"
>
ontem
</string>
<string
name=
"msg_message"
>
Messagem
</string>
<string
name=
"msg_this_room_is_read_only"
>
Este chat é apenas de leitura
</string>
<string
name=
"msg_content_description_log_in_using_facebook"
>
Fazer login através do Facebook
</string>
<string
name=
"msg_content_description_log_in_using_github"
>
Fazer login através do Github
</string>
<string
name=
"msg_content_description_log_in_using_google"
>
Fazer login através do Google
</string>
...
...
@@ -35,6 +38,6 @@
<string
name=
"msg_content_description_log_in_using_twitter"
>
Fazer login através do Twitter
</string>
<string
name=
"msg_content_description_log_in_using_gitlab"
>
Fazer login através do Gitlab
</string>
<string
name=
"msg_you"
>
Você
</string>
<string
name=
"
search"
>
Pesquisar
</string>
<string
name=
"
msg_unknown"
>
Desconhecido
</string>
</resources>
</resources>
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
6a1f37b7
...
...
@@ -12,9 +12,11 @@
<string
name=
"action_send"
>
Send
</string>
<string
name=
"action_terms_of_service"
>
Terms of Service
</string>
<string
name=
"action_privacy_policy"
>
Privacy Policy
</string>
<string
name=
"search"
>
Search
</string>
<!-- Regular information messages -->
<string
name=
"msg_no_internet_connection"
>
No internet connection
</string>
<string
name=
"msg_invalid_server_url"
>
Invalid server URL
</string>
<string
name=
"msg_generic_error"
>
Sorry, an error has occurred, please try again
</string>
<string
name=
"msg_username"
>
username
</string>
<string
name=
"msg_username_or_email"
>
username or email
</string>
...
...
@@ -22,13 +24,14 @@
<string
name=
"msg_name_and_surname"
>
name and surname
</string>
<string
name=
"msg_email"
>
email
</string>
<string
name=
"msg_or_continue_using_social_accounts"
>
Or continue using social accounts
</string>
<string
name=
"msg_new_
to_rocket_chat"
>
New to Rocket Chat
? %1$s
</string>
<string
name=
"msg_new_
user"
>
New user
? %1$s
</string>
<string
name=
"msg_new_user_agreement"
>
By proceeding you are agreeing to our\n%1$s and %2$s
</string>
<string
name=
"msg_2fa_code"
>
2FA Code
</string>
<string
name=
"msg_invalid_2fa_code"
>
Invalid 2FA Code
</string>
<string
name=
"msg_more_than_ninety_nine_unread_messages"
translatable=
"false"
>
99+
</string>
<string
name=
"msg_yesterday"
>
Yesterday
</string>
<string
name=
"msg_message"
>
Message
</string>
<string
name=
"msg_this_room_is_read_only"
>
This room is read only
</string>
<string
name=
"msg_content_description_log_in_using_facebook"
>
Login using Facebook
</string>
<string
name=
"msg_content_description_log_in_using_github"
>
Login using Github
</string>
<string
name=
"msg_content_description_log_in_using_google"
>
Login using Google
</string>
...
...
@@ -37,6 +40,6 @@
<string
name=
"msg_content_description_log_in_using_twitter"
>
Login using Twitter
</string>
<string
name=
"msg_content_description_log_in_using_gitlab"
>
Login using Gitlab
</string>
<string
name=
"msg_you"
>
You
</string>
<string
name=
"
search"
>
Search
</string>
<string
name=
"
msg_unknown"
>
Unknown
</string>
</resources>
\ No newline at end of file
build.gradle
View file @
6a1f37b7
...
...
@@ -5,6 +5,7 @@ buildscript {
repositories
{
google
()
jcenter
()
mavenCentral
()
}
dependencies
{
...
...
dependencies.gradle
View file @
6a1f37b7
...
...
@@ -7,13 +7,13 @@ ext {
kotlin
:
'1.2.10'
,
coroutine
:
'0.21'
,
dokka
:
'0.9.15'
,
kotshi
:
'0.3.0'
,
// Main dependencies
support
:
'27.0.2'
,
constraintLayout
:
'1.0.2'
,
dagger
:
'2.13'
,
exoPlayer
:
'2.6.0'
,
playServices
:
'11.8.0'
,
room
:
'1.0.0'
,
rxjava
:
'2.1.4'
,
rxandroid
:
'2.0.1'
,
...
...
@@ -23,11 +23,11 @@ ext {
threeTenABP
:
'1.0.5'
,
fresco
:
'1.7.1'
,
frescoImageViewer
:
'0.5.0'
,
kotshi
:
'0.3.0'
,
floatingSearchView
:
'2.1.1'
,
androidSvg
:
'1.2.1'
,
aVLoadingIndicatorView
:
'2.1.3'
,
textDrawable
:
'1.0.2'
,
playServices
:
'11.8.0'
,
// For testing
junit
:
'4.12'
,
...
...
@@ -52,6 +52,7 @@ ext {
daggerSupport
:
"com.google.dagger:dagger-android-support:${versions.dagger}"
,
daggerProcessor
:
"com.google.dagger:dagger-compiler:${versions.dagger}"
,
daggerAndroidApt
:
"com.google.dagger:dagger-android-processor:${versions.dagger}"
,
playServicesGcm
:
"com.google.android.gms:play-services-gcm:${versions.playServices}"
,
exoPlayer
:
"com.google.android.exoplayer:exoplayer:${versions.exoPlayer}"
,
room
:
"android.arch.persistence.room:runtime:${versions.room}"
,
...
...
@@ -63,7 +64,6 @@ ext {
moshi
:
"com.squareup.moshi:moshi:${versions.moshi}"
,
moshiKotlin
:
"com.squareup.moshi:moshi-kotlin:${versions.moshi}"
,
kotshi
:
"se.ansman.kotshi:api:${versions.kotshi}"
,
okhttp
:
"com.squareup.okhttp3:okhttp:${versions.okhttp}"
,
okhttpLogger
:
"com.squareup.okhttp3:logging-interceptor:${versions.okhttp}"
,
...
...
@@ -77,6 +77,8 @@ ext {
frescoImageViewer
:
"com.github.stfalcon:frescoimageviewer:${versions.frescoImageViewer}"
,
kotshi
:
"se.ansman.kotshi:api:${versions.kotshi}"
,
floatingSearchView
:
"com.github.arimorty:floatingsearchview:${versions.floatingSearchView}"
,
androidSvg
:
"com.caverock:androidsvg:${versions.androidSvg}"
,
...
...
@@ -85,8 +87,6 @@ ext {
textDrawable
:
"com.github.rocketchat:textdrawable:${versions.textDrawable}"
,
playServicesGcm
:
"com.google.android.gms:play-services-gcm:${versions.playServices}"
,
// For testing
junit
:
"junit:junit:$versions.junit"
,
expressoCore
:
"com.android.support.test.espresso:espresso-core:${versions.expresso}"
,
...
...
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