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
31b9a410
Commit
31b9a410
authored
Feb 28, 2018
by
Lucio Maciel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More improvements on the Socket connection/reconnection
parent
3016ef5b
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
247 additions
and
127 deletions
+247
-127
build.gradle
app/build.gradle
+2
-0
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+25
-12
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
+23
-0
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+54
-84
ChatRoomsView.kt
...at/rocket/android/chatrooms/presentation/ChatRoomsView.kt
+3
-0
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+27
-3
ConnectionManager.kt
...ocket/android/server/infraestructure/ConnectionManager.kt
+5
-3
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 @
31b9a410
...
...
@@ -60,6 +60,8 @@ dependencies {
implementation
libraries
.
constraintLayout
implementation
libraries
.
cardView
implementation
libraries
.
androidKtx
implementation
libraries
.
dagger
implementation
libraries
.
daggerSupport
kapt
libraries
.
daggerProcessor
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
31b9a410
...
...
@@ -18,6 +18,7 @@ import chat.rocket.core.internal.rest.*
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Value
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.async
import
kotlinx.coroutines.experimental.channels.Channel
import
kotlinx.coroutines.experimental.launch
...
...
@@ -73,6 +74,10 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
finally
{
view
.
hideLoading
()
}
if
(
offset
==
0L
)
{
subscribeState
()
}
}
}
...
...
@@ -146,6 +151,26 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
}
private
fun
subscribeState
()
{
Timber
.
d
(
"Subscribing to Status changes"
)
lastState
=
manager
.
state
manager
.
addStatusChannel
(
stateChannel
)
launch
(
CommonPool
+
strategy
.
jobs
)
{
for
(
state
in
stateChannel
)
{
Timber
.
d
(
"Got new state: $state - last: $lastState"
)
if
(
state
!=
lastState
)
{
launch
(
UI
)
{
view
.
showConnectionState
(
state
)
}
if
(
state
is
State
.
Connected
)
{
loadMissingMessages
()
}
}
lastState
=
state
}
}
}
private
fun
subscribeMessages
(
roomId
:
String
)
{
manager
.
subscribeRoomMessages
(
roomId
,
messagesChannel
)
...
...
@@ -156,18 +181,6 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
updateMessage
(
message
)
}
}
lastState
=
manager
.
state
manager
.
addStatusChannel
(
stateChannel
)
launch
(
CommonPool
+
strategy
.
jobs
)
{
for
(
state
in
stateChannel
)
{
Timber
.
d
(
"Got new state: $state - last: $lastState"
)
if
(
state
is
State
.
Connected
&&
lastState
!=
state
)
{
loadMissingMessages
()
}
lastState
=
state
}
}
}
private
fun
loadMissingMessages
()
{
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt
View file @
31b9a410
...
...
@@ -4,6 +4,7 @@ import android.net.Uri
import
chat.rocket.android.chatroom.viewmodel.BaseViewModel
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.core.internal.realtime.State
interface
ChatRoomView
:
LoadingView
,
MessageView
{
...
...
@@ -97,4 +98,6 @@ interface ChatRoomView : LoadingView, MessageView {
fun
clearMessageComposition
()
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 @
31b9a410
...
...
@@ -6,6 +6,8 @@ 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.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.util.extensions.addFragment
import
chat.rocket.android.util.extensions.textContent
import
dagger.android.AndroidInjection
...
...
@@ -32,6 +34,11 @@ private const val INTENT_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only"
class
ChatRoomActivity
:
AppCompatActivity
(),
HasSupportFragmentInjector
{
@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
chatRoomName
:
String
private
lateinit
var
chatRoomType
:
String
...
...
@@ -42,6 +49,9 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
super
.
onCreate
(
savedInstanceState
)
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
)
requireNotNull
(
chatRoomId
)
{
"no chat_room_id provided in Intent extras"
}
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
31b9a410
...
...
@@ -27,6 +27,7 @@ import chat.rocket.android.widget.emoji.ComposerEditText
import
chat.rocket.android.widget.emoji.Emoji
import
chat.rocket.android.widget.emoji.EmojiKeyboardPopup
import
chat.rocket.android.widget.emoji.EmojiParser
import
chat.rocket.core.internal.realtime.State
import
dagger.android.support.AndroidSupportInjection
import
io.reactivex.disposables.CompositeDisposable
import
kotlinx.android.synthetic.main.fragment_chat_room.*
...
...
@@ -290,6 +291,28 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
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
()
{
recycler_view
.
addOnScrollListener
(
object
:
RecyclerView
.
OnScrollListener
()
{
override
fun
onScrolled
(
recyclerView
:
RecyclerView
,
dx
:
Int
,
dy
:
Int
)
{
...
...
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
31b9a410
...
...
@@ -17,6 +17,7 @@ import chat.rocket.core.internal.realtime.Type
import
chat.rocket.core.model.ChatRoom
import
chat.rocket.core.model.Room
import
kotlinx.coroutines.experimental.*
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.channels.Channel
import
timber.log.Timber
import
javax.inject.Inject
...
...
@@ -44,15 +45,16 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
refreshSettingsInteractor
.
refreshAsync
(
currentServer
)
launchUI
(
strategy
)
{
view
.
showLoading
()
subscribeStatusChange
()
try
{
view
.
updateChatRooms
(
loadRooms
())
subscribeRoomUpdates
()
}
catch
(
e
:
RocketChatException
)
{
Timber
.
e
(
e
)
view
.
showMessage
(
e
.
message
!!
)
}
finally
{
view
.
hideLoading
()
}
subscribeRoomUpdates
()
}
}
...
...
@@ -111,48 +113,28 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
}
// TODO - Temporary stuff, remove when adding DB support
private
suspend
fun
subscribeRoomUpdates
()
{
/*client.addStateChannel(stateChannel)
private
suspend
fun
subscribeStatusChange
()
{
lastState
=
manager
.
state
launch
(
CommonPool
+
strategy
.
jobs
)
{
for (status in stateChannel) {
Timber.d("Changing status to: $status")
when (status) {
State.Authenticating -> Timber.d("Authenticating")
State.Connected -> {
Timber.d("Connected")
client.subscribeSubscriptions {
Timber.d("subscriptions: $it")
}
client.subscribeRooms {
Timber.d("rooms: $it")
}
for
(
state
in
stateChannel
)
{
Timber
.
d
(
"Got new state: $state - last: $lastState"
)
if
(
state
!=
lastState
)
{
launch
(
UI
)
{
view
.
showConnectionState
(
state
)
}
}
}
Timber.d("Done on statusChannel")
}
when (manager.state) {
State.Connected -> {
Timber.d("Already connected")
}
else -> client.connect()
}
launch(CommonPool + strategy.jobs) {
for (message in client.roomsChannel) {
Timber.d("Got message: $message")
updateRoom(message)
if
(
state
is
State
.
Connected
)
{
reloadRooms
()
updateRooms
()
}
}
lastState
=
state
}
}
}
launch(CommonPool + strategy.jobs) {
for (message in client.subscriptionsChannel) {
Timber.d("Got message: $message")
updateSubscription(message)
}
}*/
// TODO - Temporary stuff, remove when adding DB support
private
suspend
fun
subscribeRoomUpdates
()
{
manager
.
addStatusChannel
(
stateChannel
)
manager
.
addRoomsAndSubscriptionsChannel
(
subscriptionsChannel
)
launch
(
CommonPool
+
strategy
.
jobs
)
{
...
...
@@ -164,72 +146,60 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
}
}
lastState
=
manager
.
state
launch
(
CommonPool
+
strategy
.
jobs
)
{
for
(
state
in
stateChannel
)
{
Timber
.
d
(
"Got new state: $state - last: $lastState"
)
if
(
state
is
State
.
Connected
&&
lastState
!=
state
)
{
reloadRooms
()
updateRooms
()
}
lastState
=
state
}
}
}
private
suspend
fun
updateRoom
(
message
:
StreamMessage
<
Room
>)
{
Timber
.
d
(
"Update Room: ${message.type} - ${message.data.id} - ${message.data.name}"
)
//launchUI(strategy) {
when
(
message
.
type
)
{
Type
.
Removed
->
{
removeRoom
(
message
.
data
.
id
)
}
Type
.
Updated
->
{
updateRoom
(
message
.
data
)
}
Type
.
Inserted
->
{
// On insertion, just get all chatrooms again, since we can't create one just
// from a Room
reloadRooms
()
}
when
(
message
.
type
)
{
Type
.
Removed
->
{
removeRoom
(
message
.
data
.
id
)
}
Type
.
Updated
->
{
updateRoom
(
message
.
data
)
}
Type
.
Inserted
->
{
// On insertion, just get all chatrooms again, since we can't create one just
// from a Room
reloadRooms
()
}
}
updateRooms
()
//}
updateRooms
()
}
private
suspend
fun
updateSubscription
(
message
:
StreamMessage
<
Subscription
>)
{
Timber
.
d
(
"Update Subscription: ${message.type} - ${message.data.id} - ${message.data.name}"
)
//launchUI(strategy) {
when
(
message
.
type
)
{
Type
.
Removed
->
{
removeRoom
(
message
.
data
.
roomId
)
}
Type
.
Updated
->
{
updateSubscription
(
message
.
data
)
}
Type
.
Inserted
->
{
// On insertion, just get all chatrooms again, since we can't create one just
// from a Subscription
reloadRooms
()
}
when
(
message
.
type
)
{
Type
.
Removed
->
{
removeRoom
(
message
.
data
.
roomId
)
}
Type
.
Updated
->
{
updateSubscription
(
message
.
data
)
}
Type
.
Inserted
->
{
// On insertion, just get all chatrooms again, since we can't create one just
// from a Subscription
reloadRooms
()
}
}
updateRooms
()
//}
updateRooms
()
}
private
suspend
fun
reloadRooms
()
{
Timber
.
d
(
"realoadRooms()"
)
reloadJob
?.
cancel
()
reloadJob
=
async
(
CommonPool
+
strategy
.
jobs
)
{
delay
(
1000
)
Timber
.
d
(
"reloading rooms after wait"
)
loadRooms
()
try
{
reloadJob
=
async
(
CommonPool
+
strategy
.
jobs
)
{
delay
(
1000
)
Timber
.
d
(
"reloading rooms after wait"
)
loadRooms
()
}
reloadJob
?.
await
()
}
catch
(
ex
:
Exception
)
{
ex
.
printStackTrace
()
}
reloadJob
?.
await
()
}
// Update a ChatRoom with a Room information
...
...
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsView.kt
View file @
31b9a410
...
...
@@ -2,6 +2,7 @@ package chat.rocket.android.chatrooms.presentation
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.core.internal.realtime.State
import
chat.rocket.core.model.ChatRoom
interface
ChatRoomsView
:
LoadingView
,
MessageView
{
...
...
@@ -17,4 +18,6 @@ interface ChatRoomsView : LoadingView, MessageView {
* Shows no chat rooms to display.
*/
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 @
31b9a410
package
chat.rocket.android.chatrooms.ui
import
android.os.Bundle
import
android.os.Handler
import
android.support.v4.app.Fragment
import
android.support.v7.app.AppCompatActivity
import
android.support.v7.util.DiffUtil
...
...
@@ -13,10 +14,9 @@ import chat.rocket.android.chatrooms.presentation.ChatRoomsPresenter
import
chat.rocket.android.chatrooms.presentation.ChatRoomsView
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.SettingsRepository
import
chat.rocket.android.util.extensions.inflate
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.util.extensions.showToast
import
chat.rocket.android.util.extensions.*
import
chat.rocket.android.widget.DividerItemDecoration
import
chat.rocket.core.internal.realtime.State
import
chat.rocket.core.model.ChatRoom
import
dagger.android.support.AndroidSupportInjection
import
kotlinx.android.synthetic.main.fragment_chat_rooms.*
...
...
@@ -32,6 +32,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
@Inject
lateinit
var
serverInteractor
:
GetCurrentServerInteractor
@Inject
lateinit
var
settingsRepository
:
SettingsRepository
private
var
searchView
:
SearchView
?
=
null
private
val
handler
=
Handler
()
private
var
listJob
:
Job
?
=
null
...
...
@@ -46,6 +47,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
}
override
fun
onDestroy
()
{
handler
.
removeCallbacks
(
dismissStatus
)
presenter
.
disconnect
()
super
.
onDestroy
()
}
...
...
@@ -108,6 +110,28 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
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
()
{
(
activity
as
AppCompatActivity
).
supportActionBar
?.
title
=
getString
(
R
.
string
.
title_chats
)
}
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/ConnectionManager.kt
View file @
31b9a410
...
...
@@ -24,7 +24,8 @@ class ConnectionManager(internal val client: RocketChatClient) {
private
var
roomsId
:
String
?
=
null
fun
connect
()
{
if
(
connectJob
?.
isActive
==
true
&&
client
.
state
is
State
.
Connected
)
{
if
(
connectJob
?.
isActive
==
true
&&
(
state
!
is
State
.
Disconnected
))
{
Timber
.
d
(
"Already connected, just returning..."
)
return
}
...
...
@@ -35,8 +36,6 @@ class ConnectionManager(internal val client: RocketChatClient) {
connectJob
?.
cancel
()
// Connect and setup
client
.
connect
()
client
.
addStateChannel
(
statusChannel
)
connectJob
=
launch
{
for
(
status
in
statusChannel
)
{
...
...
@@ -92,6 +91,8 @@ class ConnectionManager(internal val client: RocketChatClient) {
}
}
client
.
connect
()
// Broadcast initial state...
val
state
=
client
.
state
for
(
channel
in
statusChannelList
)
{
...
...
@@ -109,6 +110,7 @@ class ConnectionManager(internal val client: RocketChatClient) {
}
fun
disconnect
()
{
Timber
.
d
(
"ConnectionManager DISCONNECT"
)
client
.
removeStateChannel
(
statusChannel
)
client
.
disconnect
()
connectJob
?.
cancel
()
...
...
app/src/main/java/chat/rocket/android/util/extensions/Animation.kt
View file @
31b9a410
...
...
@@ -2,7 +2,6 @@ package chat.rocket.android.util.extensions
import
android.view.View
import
android.view.ViewAnimationUtils
import
android.view.animation.AccelerateInterpolator
import
android.view.animation.DecelerateInterpolator
fun
View
.
rotateBy
(
value
:
Float
,
duration
:
Long
=
100
)
{
...
...
@@ -12,36 +11,59 @@ fun View.rotateBy(value: Float, duration: Long = 100) {
.
start
()
}
fun
View
.
fadeIn
(
startValue
:
Float
,
finishValue
:
Float
,
duration
:
Long
=
200
)
{
animate
()
.
alpha
(
startValue
)
.
setDuration
(
duration
)
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
({
animate
()
.
alpha
(
finishValue
)
.
setDuration
(
duration
)
.
setInterpolator
(
AccelerateInterpolator
()).
start
()
}).
start
()
fun
View
.
fadeIn
(
start
:
Float
=
0f
,
end
:
Float
=
1f
,
duration
:
Long
=
200
)
{
// already at end alpha, just set visible and return
if
(
alpha
==
end
)
{
setVisible
(
true
)
return
}
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
)
}
fun
View
.
fadeOut
(
startValue
:
Float
,
finishValue
:
Float
,
duration
:
Long
=
200
)
{
animate
()
.
alpha
(
startValue
)
.
setDuration
(
duration
)
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
({
animate
()
.
alpha
(
finishValue
)
.
setDuration
(
duration
)
.
setInterpolator
(
AccelerateInterpolator
()).
start
()
}).
start
()
setVisible
(
false
)
fun
View
.
fadeOut
(
start
:
Float
=
1f
,
end
:
Float
=
0f
,
duration
:
Long
=
200
)
{
if
(
alpha
==
end
)
{
setVisible
(
false
)
return
}
val
animation
=
animate
()
.
alpha
(
end
)
.
setDuration
(
duration
)
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
{
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
)
{
val
anim
=
ViewAnimationUtils
.
createCircularReveal
(
this
,
centerX
,
centerY
,
startRadius
,
endRadius
)
anim
.
duration
=
duration
...
...
app/src/main/res/layout/fragment_chat_room.xml
View file @
31b9a410
...
...
@@ -53,4 +53,19 @@
android:layout_margin=
"5dp"
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>
app/src/main/res/layout/fragment_chat_rooms.xml
View file @
31b9a410
...
...
@@ -29,4 +29,19 @@
android:visibility=
"gone"
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>
\ No newline at end of file
app/src/main/res/values-pt-rBR/strings.xml
View file @
31b9a410
...
...
@@ -84,4 +84,11 @@
<!-- Upload Messages -->
<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>
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
31b9a410
...
...
@@ -86,4 +86,12 @@
<!-- Upload Messages -->
<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>
\ No newline at end of file
dependencies.gradle
View file @
31b9a410
...
...
@@ -11,6 +11,7 @@ ext {
// Main dependencies
support
:
'27.0.2'
,
constraintLayout
:
'1.0.2'
,
androidKtx
:
'0.1'
,
dagger
:
'2.14.1'
,
exoPlayer
:
'2.6.0'
,
playServices
:
'11.8.0'
,
...
...
@@ -49,6 +50,8 @@ ext {
constraintLayout
:
"com.android.support.constraint:constraint-layout:${versions.constraintLayout}"
,
cardView
:
"com.android.support:cardview-v7:${versions.support}"
,
androidKtx
:
"androidx.core:core-ktx:${versions.androidKtx}"
,
dagger
:
"com.google.dagger:dagger:${versions.dagger}"
,
daggerSupport
:
"com.google.dagger:dagger-android-support:${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