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
1cb3f896
Unverified
Commit
1cb3f896
authored
Feb 28, 2018
by
Lucio Maciel
Committed by
GitHub
Feb 28, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #822 from RocketChat/improve-socket
[NEW] Improve socket connection
parents
3b576568
31b9a410
Changes
19
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
531 additions
and
175 deletions
+531
-175
build.gradle
app/build.gradle
+2
-0
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+70
-59
ChatRoomView.kt
...chat/rocket/android/chatroom/presentation/ChatRoomView.kt
+3
-0
ChatRoomActivity.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
+10
-0
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+24
-1
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+86
-79
ChatRoomsView.kt
...at/rocket/android/chatrooms/presentation/ChatRoomsView.kt
+3
-0
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+40
-9
MainPresenter.kt
...va/chat/rocket/android/main/presentation/MainPresenter.kt
+12
-1
MainActivity.kt
...src/main/java/chat/rocket/android/main/ui/MainActivity.kt
+8
-0
ConnectionManager.kt
...ocket/android/server/infraestructure/ConnectionManager.kt
+155
-0
ConnectionManagerFactory.kt
...ndroid/server/infraestructure/ConnectionManagerFactory.kt
+22
-0
RocketChatClientFactory.kt
...android/server/infraestructure/RocketChatClientFactory.kt
+1
-1
Animation.kt
...ain/java/chat/rocket/android/util/extensions/Animation.kt
+47
-25
fragment_chat_room.xml
app/src/main/res/layout/fragment_chat_room.xml
+15
-0
fragment_chat_rooms.xml
app/src/main/res/layout/fragment_chat_rooms.xml
+15
-0
strings.xml
app/src/main/res/values-pt-rBR/strings.xml
+7
-0
strings.xml
app/src/main/res/values/strings.xml
+8
-0
dependencies.gradle
dependencies.gradle
+3
-0
No files found.
app/build.gradle
View file @
1cb3f896
...
@@ -60,6 +60,8 @@ dependencies {
...
@@ -60,6 +60,8 @@ dependencies {
implementation
libraries
.
constraintLayout
implementation
libraries
.
constraintLayout
implementation
libraries
.
cardView
implementation
libraries
.
cardView
implementation
libraries
.
androidKtx
implementation
libraries
.
dagger
implementation
libraries
.
dagger
implementation
libraries
.
daggerSupport
implementation
libraries
.
daggerSupport
kapt
libraries
.
daggerProcessor
kapt
libraries
.
daggerProcessor
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
1cb3f896
...
@@ -6,23 +6,23 @@ import chat.rocket.android.chatroom.domain.UriInteractor
...
@@ -6,23 +6,23 @@ import chat.rocket.android.chatroom.domain.UriInteractor
import
chat.rocket.android.chatroom.viewmodel.ViewModelMapper
import
chat.rocket.android.chatroom.viewmodel.ViewModelMapper
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.state
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.RoomType
import
chat.rocket.common.model.RoomType
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.internal.realtime.State
import
chat.rocket.core.internal.realtime.State
import
chat.rocket.core.internal.realtime.connect
import
chat.rocket.core.internal.realtime.subscribeRoomMessages
import
chat.rocket.core.internal.realtime.unsubscribe
import
chat.rocket.core.internal.rest.*
import
chat.rocket.core.internal.rest.*
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Value
import
chat.rocket.core.model.Value
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.async
import
kotlinx.coroutines.experimental.async
import
kotlinx.coroutines.experimental.channels.Channel
import
kotlinx.coroutines.experimental.channels.Channel
import
kotlinx.coroutines.experimental.launch
import
kotlinx.coroutines.experimental.launch
import
org.threeten.bp.Instant
import
timber.log.Timber
import
timber.log.Timber
import
javax.inject.Inject
import
javax.inject.Inject
...
@@ -33,14 +33,22 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
...
@@ -33,14 +33,22 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
private
val
permissions
:
GetPermissionsInteractor
,
private
val
permissions
:
GetPermissionsInteractor
,
private
val
uriInteractor
:
UriInteractor
,
private
val
uriInteractor
:
UriInteractor
,
private
val
messagesRepository
:
MessagesRepository
,
private
val
messagesRepository
:
MessagesRepository
,
factory
:
RocketChatClient
Factory
,
factory
:
ConnectionManager
Factory
,
private
val
mapper
:
ViewModelMapper
)
{
private
val
mapper
:
ViewModelMapper
)
{
private
val
client
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
var
subId
:
String
?
=
null
private
val
manager
=
factory
.
create
(
currentServer
)
private
val
client
=
manager
.
client
private
var
settings
:
Map
<
String
,
Value
<
Any
>>
=
getSettingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
!!
private
var
settings
:
Map
<
String
,
Value
<
Any
>>
=
getSettingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
!!
private
val
messagesChannel
=
Channel
<
Message
>()
private
var
chatRoomId
:
String
?
=
null
private
var
chatRoomType
:
String
?
=
null
private
val
stateChannel
=
Channel
<
State
>()
private
val
stateChannel
=
Channel
<
State
>()
private
var
lastState
=
manager
.
state
fun
loadMessages
(
chatRoomId
:
String
,
chatRoomType
:
String
,
offset
:
Long
=
0
)
{
fun
loadMessages
(
chatRoomId
:
String
,
chatRoomType
:
String
,
offset
:
Long
=
0
)
{
this
.
chatRoomId
=
chatRoomId
this
.
chatRoomType
=
chatRoomType
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
view
.
showLoading
()
view
.
showLoading
()
try
{
try
{
...
@@ -55,10 +63,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
...
@@ -55,10 +63,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
val
messagesViewModels
=
mapper
.
map
(
messages
)
val
messagesViewModels
=
mapper
.
map
(
messages
)
view
.
showMessages
(
messagesViewModels
)
view
.
showMessages
(
messagesViewModels
)
// Subscribe after getting the first page of messages from REST
subscribeMessages
(
chatRoomId
)
if
(
offset
==
0L
)
{
subscribeMessages
(
chatRoomId
)
}
}
catch
(
ex
:
Exception
)
{
}
catch
(
ex
:
Exception
)
{
ex
.
printStackTrace
()
ex
.
printStackTrace
()
ex
.
message
?.
let
{
ex
.
message
?.
let
{
...
@@ -69,6 +74,10 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
...
@@ -69,6 +74,10 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
finally
{
}
finally
{
view
.
hideLoading
()
view
.
hideLoading
()
}
}
if
(
offset
==
0L
)
{
subscribeState
()
}
}
}
}
}
...
@@ -131,7 +140,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
...
@@ -131,7 +140,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
}
}
}
fun
markRoomAsRead
(
roomId
:
String
)
{
private
fun
markRoomAsRead
(
roomId
:
String
)
{
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
try
{
try
{
client
.
markAsRead
(
roomId
)
client
.
markAsRead
(
roomId
)
...
@@ -142,57 +151,70 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
...
@@ -142,57 +151,70 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
}
}
}
private
fun
subscribeMessages
(
roomId
:
String
)
{
private
fun
subscribeState
()
{
client
.
addStateChannel
(
stateChannel
)
Timber
.
d
(
"Subscribing to Status changes"
)
lastState
=
manager
.
state
manager
.
addStatusChannel
(
stateChannel
)
launch
(
CommonPool
+
strategy
.
jobs
)
{
launch
(
CommonPool
+
strategy
.
jobs
)
{
for
(
status
in
stateChannel
)
{
for
(
state
in
stateChannel
)
{
Timber
.
d
(
"Changing status to: $status"
)
Timber
.
d
(
"Got new state: $state - last: $lastState"
)
when
(
status
)
{
if
(
state
!=
lastState
)
{
State
.
Authenticating
->
Timber
.
d
(
"Authenticating"
)
launch
(
UI
)
{
State
.
Connected
->
{
view
.
showConnectionState
(
state
)
Timber
.
d
(
"Connected"
)
subId
=
client
.
subscribeRoomMessages
(
roomId
)
{
Timber
.
d
(
"subscribe messages for $roomId: $it"
)
}
}
}
}
}
Timber
.
d
(
"Done on statusChannel"
)
}
when
(
client
.
state
)
{
if
(
state
is
State
.
Connected
)
{
State
.
Connected
->
{
loadMissingMessages
()
Timber
.
d
(
"Already connected"
)
}
subId
=
client
.
subscribeRoomMessages
(
roomId
)
{
Timber
.
d
(
"subscribe messages for $roomId: $it"
)
}
}
lastState
=
state
}
}
else
->
client
.
connect
()
}
}
}
launchUI
(
strategy
)
{
private
fun
subscribeMessages
(
roomId
:
String
)
{
listenMessages
(
roomId
)
manager
.
subscribeRoomMessages
(
roomId
,
messagesChannel
)
}
// TODO - when we have a proper service, we won't need to take care of connection, just
launch
(
CommonPool
+
strategy
.
jobs
)
{
// subscribe and listen...
for
(
message
in
messagesChannel
)
{
/*launchUI(strategy) {
Timber
.
d
(
"New message for room ${message.roomId}"
)
subId = client.subscribeRoomMessages(roomId) {
updateMessage
(
message
)
Timber.d("subscribe messages for $roomId: $it")
}
}
listenMessages(roomId)
}
}*/
}
}
fun
unsubscribeMessages
()
{
private
fun
loadMissingMessages
()
{
launch
(
CommonPool
)
{
launch
(
parent
=
strategy
.
jobs
)
{
client
.
removeStateChannel
(
stateChannel
)
if
(
chatRoomId
!=
null
&&
chatRoomType
!=
null
)
{
subId
?.
let
{
subscriptionId
->
val
roomType
=
roomTypeOf
(
chatRoomType
!!
)
client
.
unsubscribe
(
subscriptionId
)
val
lastMessage
=
messagesRepository
.
getByRoomId
(
chatRoomId
!!
).
sortedByDescending
{
it
.
timestamp
}.
first
()
val
instant
=
Instant
.
ofEpochMilli
(
lastMessage
.
timestamp
)
val
messages
=
client
.
history
(
chatRoomId
!!
,
roomType
,
count
=
50
,
oldest
=
instant
.
toString
())
Timber
.
d
(
"History: $messages"
)
if
(
messages
.
result
.
isNotEmpty
())
{
val
models
=
mapper
.
map
(
messages
.
result
)
messagesRepository
.
saveAll
(
messages
.
result
)
launchUI
(
strategy
)
{
view
.
showNewMessage
(
models
)
}
if
(
messages
.
result
.
size
==
50
)
{
// we loade at least count messages, try one more to fetch more messages
loadMissingMessages
()
}
}
}
}
}
}
}
}
fun
unsubscribeMessages
(
chatRoomId
:
String
)
{
manager
.
removeStatusChannel
(
stateChannel
)
manager
.
unsubscribeRoomMessages
(
chatRoomId
)
}
/**
/**
* Delete the message with the given id.
* Delete the message with the given id.
*
*
...
@@ -317,17 +339,6 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
...
@@ -317,17 +339,6 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
}
}
}
private
suspend
fun
listenMessages
(
roomId
:
String
)
{
launch
(
CommonPool
+
strategy
.
jobs
)
{
for
(
message
in
client
.
messagesChannel
)
{
if
(
message
.
roomId
!=
roomId
)
{
Timber
.
d
(
"Ignoring message for room ${message.roomId}, expecting $roomId"
)
}
updateMessage
(
message
)
}
}
}
private
fun
updateMessage
(
streamedMessage
:
Message
)
{
private
fun
updateMessage
(
streamedMessage
:
Message
)
{
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
val
viewModelStreamedMessage
=
mapper
.
map
(
streamedMessage
)
val
viewModelStreamedMessage
=
mapper
.
map
(
streamedMessage
)
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt
View file @
1cb3f896
...
@@ -4,6 +4,7 @@ import android.net.Uri
...
@@ -4,6 +4,7 @@ import android.net.Uri
import
chat.rocket.android.chatroom.viewmodel.BaseViewModel
import
chat.rocket.android.chatroom.viewmodel.BaseViewModel
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.core.internal.realtime.State
interface
ChatRoomView
:
LoadingView
,
MessageView
{
interface
ChatRoomView
:
LoadingView
,
MessageView
{
...
@@ -97,4 +98,6 @@ interface ChatRoomView : LoadingView, MessageView {
...
@@ -97,4 +98,6 @@ interface ChatRoomView : LoadingView, MessageView {
fun
clearMessageComposition
()
fun
clearMessageComposition
()
fun
showInvalidFileSize
(
fileSize
:
Int
,
maxFileSize
:
Int
)
fun
showInvalidFileSize
(
fileSize
:
Int
,
maxFileSize
:
Int
)
fun
showConnectionState
(
state
:
State
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
View file @
1cb3f896
...
@@ -6,6 +6,8 @@ import android.os.Bundle
...
@@ -6,6 +6,8 @@ import android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v4.app.Fragment
import
android.support.v7.app.AppCompatActivity
import
android.support.v7.app.AppCompatActivity
import
chat.rocket.android.R
import
chat.rocket.android.R
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.util.extensions.addFragment
import
chat.rocket.android.util.extensions.addFragment
import
chat.rocket.android.util.extensions.textContent
import
chat.rocket.android.util.extensions.textContent
import
dagger.android.AndroidInjection
import
dagger.android.AndroidInjection
...
@@ -32,6 +34,11 @@ private const val INTENT_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only"
...
@@ -32,6 +34,11 @@ private const val INTENT_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only"
class
ChatRoomActivity
:
AppCompatActivity
(),
HasSupportFragmentInjector
{
class
ChatRoomActivity
:
AppCompatActivity
(),
HasSupportFragmentInjector
{
@Inject
lateinit
var
fragmentDispatchingAndroidInjector
:
DispatchingAndroidInjector
<
Fragment
>
@Inject
lateinit
var
fragmentDispatchingAndroidInjector
:
DispatchingAndroidInjector
<
Fragment
>
// TODO - workaround for now... We will move to a single activity
@Inject
lateinit
var
serverInteractor
:
GetCurrentServerInteractor
@Inject
lateinit
var
managerFactory
:
ConnectionManagerFactory
private
lateinit
var
chatRoomId
:
String
private
lateinit
var
chatRoomId
:
String
private
lateinit
var
chatRoomName
:
String
private
lateinit
var
chatRoomName
:
String
private
lateinit
var
chatRoomType
:
String
private
lateinit
var
chatRoomType
:
String
...
@@ -42,6 +49,9 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
...
@@ -42,6 +49,9 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
super
.
onCreate
(
savedInstanceState
)
super
.
onCreate
(
savedInstanceState
)
setContentView
(
R
.
layout
.
activity_chat_room
)
setContentView
(
R
.
layout
.
activity_chat_room
)
// Workaround for when we are coming to the app via the recents app and the app was killed.
managerFactory
.
create
(
serverInteractor
.
get
()
!!
).
connect
()
chatRoomId
=
intent
.
getStringExtra
(
INTENT_CHAT_ROOM_ID
)
chatRoomId
=
intent
.
getStringExtra
(
INTENT_CHAT_ROOM_ID
)
requireNotNull
(
chatRoomId
)
{
"no chat_room_id provided in Intent extras"
}
requireNotNull
(
chatRoomId
)
{
"no chat_room_id provided in Intent extras"
}
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
1cb3f896
...
@@ -27,6 +27,7 @@ import chat.rocket.android.widget.emoji.ComposerEditText
...
@@ -27,6 +27,7 @@ import chat.rocket.android.widget.emoji.ComposerEditText
import
chat.rocket.android.widget.emoji.Emoji
import
chat.rocket.android.widget.emoji.Emoji
import
chat.rocket.android.widget.emoji.EmojiKeyboardPopup
import
chat.rocket.android.widget.emoji.EmojiKeyboardPopup
import
chat.rocket.android.widget.emoji.EmojiParser
import
chat.rocket.android.widget.emoji.EmojiParser
import
chat.rocket.core.internal.realtime.State
import
dagger.android.support.AndroidSupportInjection
import
dagger.android.support.AndroidSupportInjection
import
io.reactivex.disposables.CompositeDisposable
import
io.reactivex.disposables.CompositeDisposable
import
kotlinx.android.synthetic.main.fragment_chat_room.*
import
kotlinx.android.synthetic.main.fragment_chat_room.*
...
@@ -112,7 +113,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
...
@@ -112,7 +113,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
}
}
override
fun
onDestroyView
()
{
override
fun
onDestroyView
()
{
presenter
.
unsubscribeMessages
()
presenter
.
unsubscribeMessages
(
chatRoomId
)
handler
.
removeCallbacksAndMessages
(
null
)
handler
.
removeCallbacksAndMessages
(
null
)
unsubscribeTextMessage
()
unsubscribeTextMessage
()
super
.
onDestroyView
()
super
.
onDestroyView
()
...
@@ -290,6 +291,28 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
...
@@ -290,6 +291,28 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
showMessage
(
getString
(
R
.
string
.
max_file_size_exceeded
,
fileSize
,
maxFileSize
))
showMessage
(
getString
(
R
.
string
.
max_file_size_exceeded
,
fileSize
,
maxFileSize
))
}
}
override
fun
showConnectionState
(
state
:
State
)
{
activity
?.
apply
{
connection_status_text
.
fadeIn
()
handler
.
removeCallbacks
(
dismissStatus
)
when
(
state
)
{
is
State
.
Connected
->
{
connection_status_text
.
text
=
getString
(
R
.
string
.
status_connected
)
handler
.
postDelayed
(
dismissStatus
,
2000
)
}
is
State
.
Disconnected
->
connection_status_text
.
text
=
getString
(
R
.
string
.
status_disconnected
)
is
State
.
Connecting
->
connection_status_text
.
text
=
getString
(
R
.
string
.
status_connecting
)
is
State
.
Authenticating
->
connection_status_text
.
text
=
getString
(
R
.
string
.
status_authenticating
)
is
State
.
Disconnecting
->
connection_status_text
.
text
=
getString
(
R
.
string
.
status_disconnecting
)
is
State
.
Waiting
->
connection_status_text
.
text
=
getString
(
R
.
string
.
status_waiting
,
state
.
seconds
)
}
}
}
private
val
dismissStatus
=
{
connection_status_text
.
fadeOut
()
}
private
fun
setupRecyclerView
()
{
private
fun
setupRecyclerView
()
{
recycler_view
.
addOnScrollListener
(
object
:
RecyclerView
.
OnScrollListener
()
{
recycler_view
.
addOnScrollListener
(
object
:
RecyclerView
.
OnScrollListener
()
{
override
fun
onScrolled
(
recyclerView
:
RecyclerView
,
dx
:
Int
,
dy
:
Int
)
{
override
fun
onScrolled
(
recyclerView
:
RecyclerView
,
dx
:
Int
,
dy
:
Int
)
{
...
...
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
1cb3f896
This diff is collapsed.
Click to expand it.
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsView.kt
View file @
1cb3f896
...
@@ -2,6 +2,7 @@ package chat.rocket.android.chatrooms.presentation
...
@@ -2,6 +2,7 @@ package chat.rocket.android.chatrooms.presentation
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.core.internal.realtime.State
import
chat.rocket.core.model.ChatRoom
import
chat.rocket.core.model.ChatRoom
interface
ChatRoomsView
:
LoadingView
,
MessageView
{
interface
ChatRoomsView
:
LoadingView
,
MessageView
{
...
@@ -17,4 +18,6 @@ interface ChatRoomsView : LoadingView, MessageView {
...
@@ -17,4 +18,6 @@ interface ChatRoomsView : LoadingView, MessageView {
* Shows no chat rooms to display.
* Shows no chat rooms to display.
*/
*/
fun
showNoChatRoomsToDisplay
()
fun
showNoChatRoomsToDisplay
()
fun
showConnectionState
(
state
:
State
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
1cb3f896
package
chat.rocket.android.chatrooms.ui
package
chat.rocket.android.chatrooms.ui
import
android.os.Bundle
import
android.os.Bundle
import
android.os.Handler
import
android.support.v4.app.Fragment
import
android.support.v4.app.Fragment
import
android.support.v7.app.AppCompatActivity
import
android.support.v7.app.AppCompatActivity
import
android.support.v7.util.DiffUtil
import
android.support.v7.util.DiffUtil
...
@@ -13,14 +14,16 @@ import chat.rocket.android.chatrooms.presentation.ChatRoomsPresenter
...
@@ -13,14 +14,16 @@ import chat.rocket.android.chatrooms.presentation.ChatRoomsPresenter
import
chat.rocket.android.chatrooms.presentation.ChatRoomsView
import
chat.rocket.android.chatrooms.presentation.ChatRoomsView
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.SettingsRepository
import
chat.rocket.android.server.domain.SettingsRepository
import
chat.rocket.android.util.extensions.inflate
import
chat.rocket.android.util.extensions.*
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.util.extensions.showToast
import
chat.rocket.android.widget.DividerItemDecoration
import
chat.rocket.android.widget.DividerItemDecoration
import
chat.rocket.core.internal.realtime.State
import
chat.rocket.core.model.ChatRoom
import
chat.rocket.core.model.ChatRoom
import
dagger.android.support.AndroidSupportInjection
import
dagger.android.support.AndroidSupportInjection
import
kotlinx.android.synthetic.main.fragment_chat_rooms.*
import
kotlinx.android.synthetic.main.fragment_chat_rooms.*
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.Job
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.async
import
kotlinx.coroutines.experimental.launch
import
kotlinx.coroutines.experimental.launch
import
javax.inject.Inject
import
javax.inject.Inject
...
@@ -29,6 +32,9 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
...
@@ -29,6 +32,9 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
@Inject
lateinit
var
serverInteractor
:
GetCurrentServerInteractor
@Inject
lateinit
var
serverInteractor
:
GetCurrentServerInteractor
@Inject
lateinit
var
settingsRepository
:
SettingsRepository
@Inject
lateinit
var
settingsRepository
:
SettingsRepository
private
var
searchView
:
SearchView
?
=
null
private
var
searchView
:
SearchView
?
=
null
private
val
handler
=
Handler
()
private
var
listJob
:
Job
?
=
null
companion
object
{
companion
object
{
fun
newInstance
()
=
ChatRoomsFragment
()
fun
newInstance
()
=
ChatRoomsFragment
()
...
@@ -41,6 +47,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
...
@@ -41,6 +47,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
}
}
override
fun
onDestroy
()
{
override
fun
onDestroy
()
{
handler
.
removeCallbacks
(
dismissStatus
)
presenter
.
disconnect
()
presenter
.
disconnect
()
super
.
onDestroy
()
super
.
onDestroy
()
}
}
...
@@ -74,17 +81,19 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
...
@@ -74,17 +81,19 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
override
suspend
fun
updateChatRooms
(
newDataSet
:
List
<
ChatRoom
>)
{
override
suspend
fun
updateChatRooms
(
newDataSet
:
List
<
ChatRoom
>)
{
activity
.
apply
{
activity
.
apply
{
launch
(
UI
)
{
listJob
?.
cancel
()
listJob
=
launch
(
UI
)
{
val
adapter
=
recycler_view
.
adapter
as
ChatRoomsAdapter
val
adapter
=
recycler_view
.
adapter
as
ChatRoomsAdapter
// FIXME https://fabric.io/rocketchat3/android/apps/chat.rocket.android.dev/issues/5a90d4718cb3c2fa63b3f557?time=last-seven-days
// FIXME https://fabric.io/rocketchat3/android/apps/chat.rocket.android.dev/issues/5a90d4718cb3c2fa63b3f557?time=last-seven-days
// TODO - fix this bug to reenable DiffUtil
// TODO - fix this bug to reenable DiffUtil
/*
val diff = async(CommonPool) {
val
diff
=
async
(
CommonPool
)
{
DiffUtil
.
calculateDiff
(
RoomsDiffCallback
(
adapter
.
dataSet
,
newDataSet
))
DiffUtil
.
calculateDiff
(
RoomsDiffCallback
(
adapter
.
dataSet
,
newDataSet
))
}.await()
*/
}.
await
()
adapter
.
updateRooms
(
newDataSet
)
if
(
isActive
)
{
adapter
.
notifyDataSetChanged
()
adapter
.
updateRooms
(
newDataSet
)
//diff.dispatchUpdatesTo(adapter)
diff
.
dispatchUpdatesTo
(
adapter
)
}
}
}
}
}
}
}
...
@@ -101,6 +110,28 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
...
@@ -101,6 +110,28 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
override
fun
showConnectionState
(
state
:
State
)
{
activity
?.
apply
{
connection_status_text
.
fadeIn
()
handler
.
removeCallbacks
(
dismissStatus
)
when
(
state
)
{
is
State
.
Connected
->
{
connection_status_text
.
text
=
getString
(
R
.
string
.
status_connected
)
handler
.
postDelayed
(
dismissStatus
,
2000
)
}
is
State
.
Disconnected
->
connection_status_text
.
text
=
getString
(
R
.
string
.
status_disconnected
)
is
State
.
Connecting
->
connection_status_text
.
text
=
getString
(
R
.
string
.
status_connecting
)
is
State
.
Authenticating
->
connection_status_text
.
text
=
getString
(
R
.
string
.
status_authenticating
)
is
State
.
Disconnecting
->
connection_status_text
.
text
=
getString
(
R
.
string
.
status_disconnecting
)
is
State
.
Waiting
->
connection_status_text
.
text
=
getString
(
R
.
string
.
status_waiting
,
state
.
seconds
)
}
}
}
private
val
dismissStatus
=
{
connection_status_text
.
fadeOut
()
}
private
fun
setupToolbar
()
{
private
fun
setupToolbar
()
{
(
activity
as
AppCompatActivity
).
supportActionBar
?.
title
=
getString
(
R
.
string
.
title_chats
)
(
activity
as
AppCompatActivity
).
supportActionBar
?.
title
=
getString
(
R
.
string
.
title_chats
)
}
}
...
...
app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt
View file @
1cb3f896
...
@@ -2,6 +2,7 @@ package chat.rocket.android.main.presentation
...
@@ -2,6 +2,7 @@ package chat.rocket.android.main.presentation
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatException
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.RocketChatClient
...
@@ -13,9 +14,11 @@ import javax.inject.Inject
...
@@ -13,9 +14,11 @@ import javax.inject.Inject
class
MainPresenter
@Inject
constructor
(
private
val
navigator
:
MainNavigator
,
class
MainPresenter
@Inject
constructor
(
private
val
navigator
:
MainNavigator
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
localRepository
:
LocalRepository
,
private
val
localRepository
:
LocalRepository
,
managerFactory
:
ConnectionManagerFactory
,
factory
:
RocketChatClientFactory
)
{
factory
:
RocketChatClientFactory
)
{
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
manager
=
managerFactory
.
create
(
currentServer
)
private
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
fun
toChatList
()
=
navigator
.
toChatList
()
fun
toChatList
()
=
navigator
.
toChatList
()
...
@@ -49,4 +52,12 @@ class MainPresenter @Inject constructor(private val navigator: MainNavigator,
...
@@ -49,4 +52,12 @@ class MainPresenter @Inject constructor(private val navigator: MainNavigator,
}
}
localRepository
.
clearAllFromServer
(
currentServer
)
localRepository
.
clearAllFromServer
(
currentServer
)
}
}
fun
connect
()
{
manager
.
connect
()
}
fun
disconnect
()
{
manager
.
disconnect
()
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt
View file @
1cb3f896
...
@@ -29,6 +29,7 @@ class MainActivity : AppCompatActivity(), MainView, HasSupportFragmentInjector {
...
@@ -29,6 +29,7 @@ class MainActivity : AppCompatActivity(), MainView, HasSupportFragmentInjector {
super
.
onCreate
(
savedInstanceState
)
super
.
onCreate
(
savedInstanceState
)
setContentView
(
R
.
layout
.
activity_main
)
setContentView
(
R
.
layout
.
activity_main
)
presenter
.
connect
()
setupToolbar
()
setupToolbar
()
setupNavigationView
()
setupNavigationView
()
}
}
...
@@ -41,6 +42,13 @@ class MainActivity : AppCompatActivity(), MainView, HasSupportFragmentInjector {
...
@@ -41,6 +42,13 @@ class MainActivity : AppCompatActivity(), MainView, HasSupportFragmentInjector {
}
}
}
}
override
fun
onDestroy
()
{
super
.
onDestroy
()
if
(
isFinishing
)
{
presenter
.
disconnect
()
}
}
override
fun
onLogout
()
{
override
fun
onLogout
()
{
finish
()
finish
()
val
intent
=
Intent
(
this
,
AuthenticationActivity
::
class
.
java
)
val
intent
=
Intent
(
this
,
AuthenticationActivity
::
class
.
java
)
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/ConnectionManager.kt
0 → 100644
View file @
1cb3f896
package
chat.rocket.android.server.infraestructure
import
chat.rocket.common.model.BaseRoom
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.realtime.*
import
chat.rocket.core.internal.rest.chatRooms
import
chat.rocket.core.model.Message
import
kotlinx.coroutines.experimental.Job
import
kotlinx.coroutines.experimental.channels.Channel
import
kotlinx.coroutines.experimental.launch
import
timber.log.Timber
class
ConnectionManager
(
internal
val
client
:
RocketChatClient
)
{
private
val
statusChannelList
=
ArrayList
<
Channel
<
State
>>()
private
val
statusChannel
=
Channel
<
State
>()
private
var
connectJob
:
Job
?
=
null
private
val
roomAndSubscriptionChannels
=
ArrayList
<
Channel
<
StreamMessage
<
BaseRoom
>>>()
private
val
roomMessagesChannels
=
LinkedHashMap
<
String
,
Channel
<
Message
>>()
private
val
subscriptionIdMap
=
HashMap
<
String
,
String
>()
private
var
subscriptionId
:
String
?
=
null
private
var
roomsId
:
String
?
=
null
fun
connect
()
{
if
(
connectJob
?.
isActive
==
true
&&
(
state
!
is
State
.
Disconnected
))
{
Timber
.
d
(
"Already connected, just returning..."
)
return
}
// cleanup first
client
.
removeStateChannel
(
statusChannel
)
client
.
disconnect
()
connectJob
?.
cancel
()
// Connect and setup
client
.
addStateChannel
(
statusChannel
)
connectJob
=
launch
{
for
(
status
in
statusChannel
)
{
Timber
.
d
(
"Changing status to: $status"
)
when
(
status
)
{
is
State
.
Connected
->
{
client
.
subscribeSubscriptions
{
_
,
id
->
Timber
.
d
(
"Subscribed to subscriptions: $id"
)
subscriptionId
=
id
}
client
.
subscribeRooms
{
_
,
id
->
Timber
.
d
(
"Subscribed to rooms: $id"
)
roomsId
=
id
}
resubscribeRooms
()
}
is
State
.
Waiting
->
{
Timber
.
d
(
"Connection in: ${status.seconds}"
)
}
}
for
(
channel
in
statusChannelList
)
{
channel
.
send
(
status
)
}
}
}
launch
(
parent
=
connectJob
)
{
for
(
room
in
client
.
roomsChannel
)
{
Timber
.
d
(
"GOT Room streamed"
)
for
(
channel
in
roomAndSubscriptionChannels
)
{
channel
.
send
(
room
)
}
}
}
launch
(
parent
=
connectJob
)
{
for
(
subscription
in
client
.
subscriptionsChannel
)
{
Timber
.
d
(
"GOT Subscription streamed"
)
for
(
channel
in
roomAndSubscriptionChannels
)
{
channel
.
send
(
subscription
)
}
}
}
launch
(
parent
=
connectJob
)
{
for
(
message
in
client
.
messagesChannel
)
{
Timber
.
d
(
"Received new Message for room ${message.roomId}"
)
val
channel
=
roomMessagesChannels
[
message
.
roomId
]
channel
?.
send
(
message
)
}
}
client
.
connect
()
// Broadcast initial state...
val
state
=
client
.
state
for
(
channel
in
statusChannelList
)
{
channel
.
offer
(
state
)
}
}
private
fun
resubscribeRooms
()
{
roomMessagesChannels
.
toList
().
map
{
(
roomId
,
channel
)
->
client
.
subscribeRoomMessages
(
roomId
)
{
_
,
id
->
Timber
.
d
(
"Subscribed to $roomId: $id"
)
subscriptionIdMap
[
roomId
]
=
id
}
}
}
fun
disconnect
()
{
Timber
.
d
(
"ConnectionManager DISCONNECT"
)
client
.
removeStateChannel
(
statusChannel
)
client
.
disconnect
()
connectJob
?.
cancel
()
}
fun
addStatusChannel
(
channel
:
Channel
<
State
>)
=
statusChannelList
.
add
(
channel
)
fun
removeStatusChannel
(
channel
:
Channel
<
State
>)
=
statusChannelList
.
remove
(
channel
)
fun
addRoomsAndSubscriptionsChannel
(
channel
:
Channel
<
StreamMessage
<
BaseRoom
>>)
=
roomAndSubscriptionChannels
.
add
(
channel
)
fun
removeRoomsAndSubscriptionsChannel
(
channel
:
Channel
<
StreamMessage
<
BaseRoom
>>)
=
roomAndSubscriptionChannels
.
remove
(
channel
)
fun
subscribeRoomMessages
(
roomId
:
String
,
channel
:
Channel
<
Message
>)
{
val
oldSub
=
roomMessagesChannels
.
put
(
roomId
,
channel
)
if
(
oldSub
!=
null
)
{
Timber
.
d
(
"Room $roomId already subscribed..."
)
return
}
if
(
client
.
state
is
State
.
Connected
)
{
client
.
subscribeRoomMessages
(
roomId
)
{
_
,
id
->
Timber
.
d
(
"Subscribed to $roomId: $id"
)
subscriptionIdMap
[
roomId
]
=
id
}
}
}
fun
unsubscribeRoomMessages
(
roomId
:
String
)
{
val
sub
=
roomMessagesChannels
.
remove
(
roomId
)
if
(
sub
!=
null
)
{
val
id
=
subscriptionIdMap
.
remove
(
roomId
)
id
?.
let
{
client
.
unsubscribe
(
it
)
}
}
}
}
suspend
fun
ConnectionManager
.
chatRooms
(
timestamp
:
Long
=
0
,
filterCustom
:
Boolean
=
true
)
=
client
.
chatRooms
(
timestamp
,
filterCustom
)
val
ConnectionManager
.
state
:
State
get
()
=
client
.
state
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/infraestructure/ConnectionManagerFactory.kt
0 → 100644
View file @
1cb3f896
package
chat.rocket.android.server.infraestructure
import
timber.log.Timber
import
javax.inject.Inject
import
javax.inject.Singleton
@Singleton
class
ConnectionManagerFactory
@Inject
constructor
(
private
val
factory
:
RocketChatClientFactory
)
{
private
val
cache
=
HashMap
<
String
,
ConnectionManager
>()
fun
create
(
url
:
String
):
ConnectionManager
{
cache
[
url
]
?.
let
{
Timber
.
d
(
"Returning CACHED Manager for: $url"
)
return
it
}
Timber
.
d
(
"Returning FRESH Manager for: $url"
)
val
manager
=
ConnectionManager
(
factory
.
create
(
url
))
cache
[
url
]
=
manager
return
manager
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/infraestructure/RocketChatClientFactory.kt
View file @
1cb3f896
...
@@ -28,7 +28,7 @@ class RocketChatClientFactory @Inject constructor(val okHttpClient: OkHttpClient
...
@@ -28,7 +28,7 @@ class RocketChatClientFactory @Inject constructor(val okHttpClient: OkHttpClient
}
}
Timber
.
d
(
"Returning NEW client for: $url"
)
Timber
.
d
(
"Returning NEW client for: $url"
)
cache
.
put
(
url
,
client
)
cache
[
url
]
=
client
return
client
return
client
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Animation.kt
View file @
1cb3f896
...
@@ -2,7 +2,6 @@ package chat.rocket.android.util.extensions
...
@@ -2,7 +2,6 @@ package chat.rocket.android.util.extensions
import
android.view.View
import
android.view.View
import
android.view.ViewAnimationUtils
import
android.view.ViewAnimationUtils
import
android.view.animation.AccelerateInterpolator
import
android.view.animation.DecelerateInterpolator
import
android.view.animation.DecelerateInterpolator
fun
View
.
rotateBy
(
value
:
Float
,
duration
:
Long
=
100
)
{
fun
View
.
rotateBy
(
value
:
Float
,
duration
:
Long
=
100
)
{
...
@@ -12,36 +11,59 @@ fun View.rotateBy(value: Float, duration: Long = 100) {
...
@@ -12,36 +11,59 @@ fun View.rotateBy(value: Float, duration: Long = 100) {
.
start
()
.
start
()
}
}
fun
View
.
fadeIn
(
startValue
:
Float
,
finishValue
:
Float
,
duration
:
Long
=
200
)
{
fun
View
.
fadeIn
(
start
:
Float
=
0f
,
end
:
Float
=
1f
,
duration
:
Long
=
200
)
{
animate
()
// already at end alpha, just set visible and return
.
alpha
(
startValue
)
if
(
alpha
==
end
)
{
.
setDuration
(
duration
)
setVisible
(
true
)
.
setInterpolator
(
DecelerateInterpolator
())
return
.
withEndAction
({
}
animate
()
.
alpha
(
finishValue
)
.
setDuration
(
duration
)
.
setInterpolator
(
AccelerateInterpolator
()).
start
()
}).
start
()
val
animation
=
animate
()
.
alpha
(
end
)
.
setDuration
(
duration
)
.
setInterpolator
(
DecelerateInterpolator
())
if
(
start
!=
alpha
)
{
animate
()
.
alpha
(
start
)
.
setDuration
(
duration
/
2
)
// half the time, so the entire animation runs on duration
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
{
animation
.
setDuration
(
duration
/
2
).
start
()
}.
start
()
}
else
{
animation
.
start
()
}
setVisible
(
true
)
setVisible
(
true
)
}
}
fun
View
.
fadeOut
(
startValue
:
Float
,
finishValue
:
Float
,
duration
:
Long
=
200
)
{
fun
View
.
fadeOut
(
start
:
Float
=
1f
,
end
:
Float
=
0f
,
duration
:
Long
=
200
)
{
animate
()
if
(
alpha
==
end
)
{
.
alpha
(
startValue
)
setVisible
(
false
)
.
setDuration
(
duration
)
return
.
setInterpolator
(
DecelerateInterpolator
())
}
.
withEndAction
({
animate
()
val
animation
=
animate
()
.
alpha
(
finishValue
)
.
alpha
(
end
)
.
setDuration
(
duration
)
.
setDuration
(
duration
)
.
setInterpolator
(
AccelerateInterpolator
()).
start
()
.
setInterpolator
(
DecelerateInterpolator
())
}).
start
()
.
withEndAction
{
setVisible
(
false
)
setVisible
(
false
)
}
if
(
start
!=
alpha
)
{
animate
()
.
alpha
(
start
)
.
setDuration
(
duration
/
2
)
// half the time, so the entire animation runs on duration
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
{
animation
.
setDuration
(
duration
/
2
).
start
()
}.
start
()
}
else
{
animation
.
start
()
}
}
}
fun
View
.
circularRevealOrUnreveal
(
centerX
:
Int
,
centerY
:
Int
,
startRadius
:
Float
,
endRadius
:
Float
,
duration
:
Long
=
200
)
{
fun
View
.
circularRevealOrUnreveal
(
centerX
:
Int
,
centerY
:
Int
,
startRadius
:
Float
,
endRadius
:
Float
,
duration
:
Long
=
200
)
{
val
anim
=
ViewAnimationUtils
.
createCircularReveal
(
this
,
centerX
,
centerY
,
startRadius
,
endRadius
)
val
anim
=
ViewAnimationUtils
.
createCircularReveal
(
this
,
centerX
,
centerY
,
startRadius
,
endRadius
)
anim
.
duration
=
duration
anim
.
duration
=
duration
...
...
app/src/main/res/layout/fragment_chat_room.xml
View file @
1cb3f896
...
@@ -53,4 +53,19 @@
...
@@ -53,4 +53,19 @@
android:layout_margin=
"5dp"
android:layout_margin=
"5dp"
android:visibility=
"gone"
/>
android:visibility=
"gone"
/>
<TextView
android:id=
"@+id/connection_status_text"
android:layout_width=
"match_parent"
android:layout_height=
"32dp"
android:background=
"@color/colorPrimary"
android:elevation=
"4dp"
android:textColor=
"@color/white"
android:gravity=
"center"
android:textAppearance=
"@style/TextAppearance.AppCompat.Body2"
android:visibility=
"gone"
android:alpha=
"0"
tools:alpha=
"1"
tools:visibility=
"visible"
tools:text=
"connected"
/>
</RelativeLayout>
</RelativeLayout>
app/src/main/res/layout/fragment_chat_rooms.xml
View file @
1cb3f896
...
@@ -29,4 +29,19 @@
...
@@ -29,4 +29,19 @@
android:visibility=
"gone"
android:visibility=
"gone"
tools:visibility=
"visible"
/>
tools:visibility=
"visible"
/>
<TextView
android:id=
"@+id/connection_status_text"
android:layout_width=
"match_parent"
android:layout_height=
"32dp"
android:background=
"@color/colorPrimary"
android:elevation=
"4dp"
android:textColor=
"@color/white"
android:gravity=
"center"
android:textAppearance=
"@style/TextAppearance.AppCompat.Body2"
android:visibility=
"gone"
android:alpha=
"0"
tools:alpha=
"1"
tools:visibility=
"visible"
tools:text=
"connected"
/>
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/values-pt-rBR/strings.xml
View file @
1cb3f896
...
@@ -84,4 +84,11 @@
...
@@ -84,4 +84,11 @@
<!-- Upload Messages -->
<!-- Upload Messages -->
<string
name=
"max_file_size_exceeded"
>
Tamanho de arquivo (%1$d bytes) excedeu tamanho máximo de upload (%2$d bytes)
</string>
<string
name=
"max_file_size_exceeded"
>
Tamanho de arquivo (%1$d bytes) excedeu tamanho máximo de upload (%2$d bytes)
</string>
<!-- Socket status -->
<string
name=
"status_connected"
>
conectado
</string>
<string
name=
"status_disconnected"
>
desconetado
</string>
<string
name=
"status_connecting"
>
conectando
</string>
<string
name=
"status_authenticating"
>
autenticando
</string>
<string
name=
"status_disconnecting"
>
desconectando
</string>
<string
name=
"status_waiting"
>
conectando em %d segundos
</string>
</resources>
</resources>
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
1cb3f896
...
@@ -86,4 +86,12 @@
...
@@ -86,4 +86,12 @@
<!-- Upload Messages -->
<!-- Upload Messages -->
<string
name=
"max_file_size_exceeded"
>
File size %1$d bytes exceeded max upload size of %2$d bytes
</string>
<string
name=
"max_file_size_exceeded"
>
File size %1$d bytes exceeded max upload size of %2$d bytes
</string>
<!-- Socket status -->
<string
name=
"status_connected"
>
connected
</string>
<string
name=
"status_disconnected"
>
disconnected
</string>
<string
name=
"status_connecting"
>
connecting
</string>
<string
name=
"status_authenticating"
>
authenticating
</string>
<string
name=
"status_disconnecting"
>
disconnecting
</string>
<string
name=
"status_waiting"
>
connecting in %d seconds
</string>
</resources>
</resources>
\ No newline at end of file
dependencies.gradle
View file @
1cb3f896
...
@@ -11,6 +11,7 @@ ext {
...
@@ -11,6 +11,7 @@ ext {
// Main dependencies
// Main dependencies
support
:
'27.0.2'
,
support
:
'27.0.2'
,
constraintLayout
:
'1.0.2'
,
constraintLayout
:
'1.0.2'
,
androidKtx
:
'0.1'
,
dagger
:
'2.14.1'
,
dagger
:
'2.14.1'
,
exoPlayer
:
'2.6.0'
,
exoPlayer
:
'2.6.0'
,
playServices
:
'11.8.0'
,
playServices
:
'11.8.0'
,
...
@@ -49,6 +50,8 @@ ext {
...
@@ -49,6 +50,8 @@ ext {
constraintLayout
:
"com.android.support.constraint:constraint-layout:${versions.constraintLayout}"
,
constraintLayout
:
"com.android.support.constraint:constraint-layout:${versions.constraintLayout}"
,
cardView
:
"com.android.support:cardview-v7:${versions.support}"
,
cardView
:
"com.android.support:cardview-v7:${versions.support}"
,
androidKtx
:
"androidx.core:core-ktx:${versions.androidKtx}"
,
dagger
:
"com.google.dagger:dagger:${versions.dagger}"
,
dagger
:
"com.google.dagger:dagger:${versions.dagger}"
,
daggerSupport
:
"com.google.dagger:dagger-android-support:${versions.dagger}"
,
daggerSupport
:
"com.google.dagger:dagger-android-support:${versions.dagger}"
,
daggerProcessor
:
"com.google.dagger:dagger-compiler:${versions.dagger}"
,
daggerProcessor
:
"com.google.dagger:dagger-compiler:${versions.dagger}"
,
...
...
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