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
d4d4f52c
Unverified
Commit
d4d4f52c
authored
May 10, 2018
by
Filipe de Lima Brito
Committed by
GitHub
May 10, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1254 from RocketChat/new/listen-to-typing-status
[NEW] Listen to typing status
parents
c5302609
1f901f3c
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
195 additions
and
49 deletions
+195
-49
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+58
-9
ChatRoomView.kt
...chat/rocket/android/chatroom/presentation/ChatRoomView.kt
+12
-0
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+47
-3
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+2
-5
ConnectionManager.kt
...ocket/android/server/infraestructure/ConnectionManager.kt
+1
-1
fragment_chat_room.xml
app/src/main/res/layout/fragment_chat_room.xml
+43
-31
strings.xml
app/src/main/res/values-es/strings.xml
+8
-0
strings.xml
app/src/main/res/values-fr/strings.xml
+8
-0
strings.xml
app/src/main/res/values-hi-rIN/strings.xml
+8
-0
strings.xml
app/src/main/res/values-pt-rBR/strings.xml
+4
-0
strings.xml
app/src/main/res/values/strings.xml
+4
-0
No files found.
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
d4d4f52c
...
...
@@ -29,6 +29,8 @@ import chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.internal.realtime.setTypingStatus
import
chat.rocket.core.internal.realtime.socket.model.State
import
chat.rocket.core.internal.realtime.subscribeTypingStatus
import
chat.rocket.core.internal.realtime.unsubscribe
import
chat.rocket.core.internal.rest.*
import
chat.rocket.core.model.Command
import
chat.rocket.core.model.Message
...
...
@@ -70,8 +72,11 @@ class ChatRoomPresenter @Inject constructor(
private
var
chatRoomId
:
String
?
=
null
private
var
chatRoomType
:
String
?
=
null
private
val
stateChannel
=
Channel
<
State
>()
private
var
typingStatusSubscriptionId
:
String
?
=
null
private
var
lastState
=
manager
.
state
private
var
typingStatusList
=
arrayListOf
<
String
>()
fun
setupChatRoom
()
{
launchUI
(
strategy
)
{
...
...
@@ -115,6 +120,7 @@ class ChatRoomPresenter @Inject constructor(
view
.
hideLoading
()
}
subscribeTypingStatus
()
if
(
offset
==
0L
)
{
subscribeState
()
}
...
...
@@ -326,14 +332,6 @@ class ChatRoomPresenter @Inject constructor(
}
}
fun
unsubscribeMessages
(
chatRoomId
:
String
)
{
manager
.
removeStatusChannel
(
stateChannel
)
manager
.
unsubscribeRoomMessages
(
chatRoomId
)
// All messages during the subscribed period are assumed to be read,
// and lastSeen is updated as the time when the user leaves the room
markRoomAsRead
(
chatRoomId
)
}
/**
* Delete the message with the given id.
*
...
...
@@ -651,6 +649,57 @@ class ChatRoomPresenter @Inject constructor(
}
}
fun
disconnect
()
{
unsubscribeTypingStatus
()
if
(
chatRoomId
!=
null
)
{
unsubscribeMessages
(
chatRoomId
.
toString
())
}
}
private
suspend
fun
subscribeTypingStatus
()
{
client
.
subscribeTypingStatus
(
chatRoomId
.
toString
())
{
_
,
id
->
typingStatusSubscriptionId
=
id
}
for
(
typingStatus
in
client
.
typingStatusChannel
)
{
processTypingStatus
(
typingStatus
)
}
}
private
fun
processTypingStatus
(
typingStatus
:
Pair
<
String
,
Boolean
>)
{
if
(!
typingStatusList
.
any
{
username
->
username
==
typingStatus
.
first
})
{
if
(
typingStatus
.
second
)
{
typingStatusList
.
add
(
typingStatus
.
first
)
}
}
else
{
typingStatusList
.
find
{
username
->
username
==
typingStatus
.
first
}
?.
let
{
typingStatusList
.
remove
(
it
)
if
(
typingStatus
.
second
)
{
typingStatusList
.
add
(
typingStatus
.
first
)
}
}
}
if
(
typingStatusList
.
isNotEmpty
())
{
view
.
showTypingStatus
(
typingStatusList
)
}
else
{
view
.
hideTypingStatusView
()
}
}
private
fun
unsubscribeTypingStatus
()
{
typingStatusSubscriptionId
?.
let
{
client
.
unsubscribe
(
it
)
}
}
private
fun
unsubscribeMessages
(
chatRoomId
:
String
)
{
manager
.
removeStatusChannel
(
stateChannel
)
manager
.
unsubscribeRoomMessages
(
chatRoomId
)
// All messages during the subscribed period are assumed to be read,
// and lastSeen is updated as the time when the user leaves the room
markRoomAsRead
(
chatRoomId
)
}
private
fun
updateMessage
(
streamedMessage
:
Message
)
{
launchUI
(
strategy
)
{
val
viewModelStreamedMessage
=
mapper
.
map
(
streamedMessage
)
...
...
@@ -667,4 +716,4 @@ class ChatRoomPresenter @Inject constructor(
}
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt
View file @
d4d4f52c
...
...
@@ -25,6 +25,18 @@ interface ChatRoomView : LoadingView, MessageView {
*/
fun
sendMessage
(
text
:
String
)
/**
* Shows the username(s) of the user(s) who is/are typing in the chat room.
*
* @param usernameList The list of username to show.
*/
fun
showTypingStatus
(
usernameList
:
ArrayList
<
String
>)
/**
* Hides the typing status view.
*/
fun
hideTypingStatusView
()
/**
* Perform file selection with the mime type [filter]
*/
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
d4d4f52c
...
...
@@ -13,7 +13,10 @@ import android.support.v4.app.Fragment
import
android.support.v7.widget.DefaultItemAnimator
import
android.support.v7.widget.LinearLayoutManager
import
android.support.v7.widget.RecyclerView
import
android.text.SpannableStringBuilder
import
android.view.*
import
androidx.core.text.bold
import
androidx.core.view.isVisible
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.adapter.*
import
chat.rocket.android.chatroom.presentation.ChatRoomPresenter
...
...
@@ -94,8 +97,18 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
private
var
playComposeMessageButtonsAnimation
=
true
// For reveal and unreveal anim.
private
val
hypotenuse
by
lazy
{
Math
.
hypot
(
root_layout
.
width
.
toDouble
(),
root_layout
.
height
.
toDouble
()).
toFloat
()
}
private
val
max
by
lazy
{
Math
.
max
(
layout_message_attachment_options
.
width
.
toDouble
(),
layout_message_attachment_options
.
height
.
toDouble
()).
toFloat
()
}
private
val
hypotenuse
by
lazy
{
Math
.
hypot
(
root_layout
.
width
.
toDouble
(),
root_layout
.
height
.
toDouble
()
).
toFloat
()
}
private
val
max
by
lazy
{
Math
.
max
(
layout_message_attachment_options
.
width
.
toDouble
(),
layout_message_attachment_options
.
height
.
toDouble
()
).
toFloat
()
}
private
val
centerX
by
lazy
{
recycler_view
.
right
}
private
val
centerY
by
lazy
{
recycler_view
.
bottom
}
private
val
handler
=
Handler
()
...
...
@@ -155,7 +168,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
recycler_view
.
removeOnScrollListener
(
onScrollListener
)
recycler_view
.
removeOnLayoutChangeListener
(
layoutChangeListener
)
presenter
.
unsubscribeMessages
(
chatRoomId
)
presenter
.
disconnect
(
)
handler
.
removeCallbacksAndMessages
(
null
)
unsubscribeComposeTextMessage
()
...
...
@@ -319,6 +332,37 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
}
override
fun
showTypingStatus
(
usernameList
:
ArrayList
<
String
>)
{
ui
{
when
(
usernameList
.
size
)
{
1
->
{
text_typing_status
.
text
=
SpannableStringBuilder
()
.
bold
{
append
(
usernameList
[
0
])
}
.
append
(
getString
(
R
.
string
.
msg_is_typing
))
}
2
->
{
text_typing_status
.
text
=
SpannableStringBuilder
()
.
bold
{
append
(
usernameList
[
0
])
}
.
append
(
getString
(
R
.
string
.
msg_and
))
.
bold
{
append
(
usernameList
[
1
])
}
.
append
(
getString
(
R
.
string
.
msg_are_typing
))
}
else
->
{
text_typing_status
.
text
=
getString
(
R
.
string
.
msg_several_users_are_typing
)
}
}
text_typing_status
.
isVisible
=
true
}
}
override
fun
hideTypingStatusView
()
{
ui
{
text_typing_status
.
isVisible
=
false
}
}
override
fun
uploadFile
(
uri
:
Uri
)
{
// TODO Just leaving a blank message that comes with the file for now. In the future lets add the possibility to add a message with the file to be uploaded.
presenter
.
uploadFile
(
chatRoomId
,
uri
,
""
)
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
d4d4f52c
...
...
@@ -14,6 +14,7 @@ import android.support.v7.widget.SearchView
import
android.view.*
import
android.widget.CheckBox
import
android.widget.RadioGroup
import
androidx.core.view.isVisible
import
chat.rocket.android.R
import
chat.rocket.android.chatrooms.presentation.ChatRoomsPresenter
import
chat.rocket.android.chatrooms.presentation.ChatRoomsView
...
...
@@ -166,11 +167,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
/*val diff = async(CommonPool) {
DiffUtil.calculateDiff(RoomsDiffCallback(adapter.baseAdapter.dataSet, newDataSet))
}.await()*/
if
(
newDataSet
.
isEmpty
())
{
text_no_search
.
visibility
=
View
.
VISIBLE
}
else
{
text_no_search
.
visibility
=
View
.
GONE
}
text_no_search
.
isVisible
=
newDataSet
.
isEmpty
()
if
(
isActive
)
{
adapter
.
baseAdapter
.
updateRooms
(
newDataSet
)
// TODO - fix crash to re-enable diff.dispatchUpdatesTo(adapter)
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/ConnectionManager.kt
View file @
d4d4f52c
...
...
@@ -110,7 +110,6 @@ class ConnectionManager(internal val client: RocketChatClient) {
Timber
.
d
(
"Received new Message for room ${message.roomId}"
)
val
channel
=
roomMessagesChannels
[
message
.
roomId
]
channel
?.
send
(
message
)
}
}
...
...
@@ -131,6 +130,7 @@ class ConnectionManager(internal val client: RocketChatClient) {
}
}
}
client
.
connect
()
// Broadcast initial state...
...
...
app/src/main/res/layout/fragment_chat_room.xml
View file @
d4d4f52c
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/root_layout"
...
...
@@ -12,23 +11,23 @@
android:id=
"@+id/view_loading"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
android:visibility=
"gone"
app:indicatorColor=
"@color/black"
app:indicatorName=
"BallPulseIndicator"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
tools:visibility=
"visible"
/>
<FrameLayout
android:id=
"@+id/message_list_container"
android:layout_width=
"0dp"
android:layout_height=
"0dp"
app:layout_constraint
Start_toStartOf=
"parent
"
app:layout_constraint
Bottom_toTopOf=
"@id/text_typing_status
"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraint
Top_toTop
Of=
"parent"
app:layout_constraint
Bottom_toTopOf=
"@id/layout_message_composer
"
>
app:layout_constraint
Start_toStart
Of=
"parent"
app:layout_constraint
Top_toTopOf=
"parent
"
>
<include
android:id=
"@+id/layout_message_list"
...
...
@@ -44,52 +43,65 @@
android:layout_height=
"100dp"
android:src=
"@drawable/ic_chat_black_24dp"
android:tint=
"@color/icon_grey"
app:layout_constraintStart_toStartOf=
"parent"
android:visibility=
"gone"
app:layout_constraintBottom_toTopOf=
"@id/text_chat_title"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toTopOf=
"@id/text_chat_title"
app:layout_constraintVertical_chainStyle=
"packed"
android:visibility=
"gone"
tools:visibility=
"visible"
/>
<TextView
android:id=
"@+id/text_chat_title"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"24dp"
android:text=
"@string/msg_no_chat_title"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@id/image_chat_icon"
app:layout_constraintBottom_toTopOf=
"@id/text_chat_description"
android:textColor=
"@color/colorSecondaryText"
android:textSize=
"20sp"
android:layout_marginTop=
"24dp"
android:textStyle=
"bold"
android:textColor=
"@color/colorSecondaryText"
android:visibility=
"gone"
tools:visibility=
"visible"
/>
app:layout_constraintBottom_toTopOf=
"@id/text_chat_description"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@id/image_chat_icon"
tools:visibility=
"visible"
/>
<TextView
android:id=
"@+id/text_chat_description"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"@string/msg_no_chat_description"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@id/text_chat_title"
app:layout_constraintBottom_toTopOf=
"@id/layout_message_composer"
android:layout_marginTop=
"16dp"
android:text=
"@string/msg_no_chat_description"
android:textAlignment=
"center"
android:textSize=
"16sp"
android:textColor=
"@color/colorSecondaryTextLight"
android:textSize=
"16sp"
android:visibility=
"gone"
tools:visibility=
"visible"
/>
app:layout_constraintBottom_toTopOf=
"@id/layout_message_composer"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@id/text_chat_title"
tools:visibility=
"visible"
/>
<chat.rocket.android.widget.autocompletion.ui.SuggestionsView
android:id=
"@+id/suggestions_view"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"@color/suggestion_background_color"
app:layout_constraintBottom_toTopOf=
"@id/layout_message_composer"
/>
<TextView
android:id=
"@+id/text_typing_status"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"5dp"
android:layout_marginEnd=
"16dp"
android:layout_marginStart=
"16dp"
android:layout_marginTop=
"16dp"
android:maxLines=
"2"
android:visibility=
"gone"
app:layout_constraintBottom_toTopOf=
"@id/layout_message_composer"
a
ndroid:background=
"@color/suggestion_background_color
"
/>
a
pp:layout_constraintEnd_toStartOf=
"parent
"
/>
<include
android:id=
"@+id/layout_message_composer"
...
...
@@ -102,18 +114,18 @@
android:id=
"@+id/view_dim"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
app:layout_constraintBottom_toTopOf=
"@id/layout_message_composer"
android:background=
"@color/colorDim"
android:visibility=
"gone"
/>
android:visibility=
"gone"
app:layout_constraintBottom_toTopOf=
"@id/layout_message_composer"
/>
<include
android:id=
"@+id/layout_message_attachment_options"
layout=
"@layout/message_attachment_options"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
app:layout_constraintBottom_toTopOf=
"@id/layout_message_composer"
android:layout_margin=
"5dp"
android:visibility=
"gone"
/>
android:visibility=
"gone"
app:layout_constraintBottom_toTopOf=
"@id/layout_message_composer"
/>
<TextView
android:id=
"@+id/connection_status_text"
...
...
app/src/main/res/values-es/strings.xml
View file @
d4d4f52c
...
...
@@ -111,6 +111,14 @@
<string
name=
"msg_no_chat_title"
>
Sin mensajes de chat
</string>
<string
name=
"msg_no_chat_description"
>
Comience a conversar para ver\nsus mensajes aquí.
</string>
<string
name=
"msg_edited"
>
(editado)
</string>
// TODO: Add proper translation.
<string
name=
"msg_and"
>
\u0020and\u0020
</string>
// TODO: Add proper translation.
<string
name=
"msg_is_typing"
>
\u0020is typing…
</string>
// TODO: Add proper translation.
<string
name=
"msg_are_typing"
>
\u0020are typing…
</string>
// TODO: Add proper translation.
<string
name=
"msg_several_users_are_typing"
>
Several users are typing…
</string>
<string
name=
"msg_no_search_found"
>
No se han encontrado resultados
</string>
<!-- System messages -->
...
...
app/src/main/res/values-fr/strings.xml
View file @
d4d4f52c
...
...
@@ -111,6 +111,14 @@
<string
name=
"msg_no_chat_title"
>
Aucun message de discussion
</string>
<string
name=
"msg_no_chat_description"
>
Commencez à converser pour voir\nvos messages ici.
</string>
<string
name=
"msg_edited"
>
(édité)
</string>
// TODO: Add proper translation.
<string
name=
"msg_and"
>
\u0020and\u0020
</string>
// TODO: Add proper translation.
<string
name=
"msg_is_typing"
>
\u0020is typing…
</string>
// TODO: Add proper translation.
<string
name=
"msg_are_typing"
>
\u0020are typing…
</string>
// TODO: Add proper translation.
<string
name=
"msg_several_users_are_typing"
>
Several users are typing…
</string>
<string
name=
"msg_no_search_found"
>
Aucun résultat trouvé
</string>
<!-- System messages -->
...
...
app/src/main/res/values-hi-rIN/strings.xml
View file @
d4d4f52c
...
...
@@ -113,6 +113,14 @@
<string
name=
"msg_no_chat_title"
>
कोई चैट संदेश नहीं
</string>
<string
name=
"msg_no_chat_description"
>
यहां अपने संदेश देखने के लिए\nबातचीत शुरू करें।
</string>
<string
name=
"msg_edited"
>
(संपादित)
</string>
// TODO: Add proper translation.
<string
name=
"msg_and"
>
\u0020and\u0020
</string>
// TODO: Add proper translation.
<string
name=
"msg_is_typing"
>
\u0020is typing…
</string>
// TODO: Add proper translation.
<string
name=
"msg_are_typing"
>
\u0020are typing…
</string>
// TODO: Add proper translation.
<string
name=
"msg_several_users_are_typing"
>
Several users are typing…
</string>
<string
name=
"msg_no_search_found"
>
कोई परिणाम नहीं मिला
</string>
<!-- System messages -->
...
...
app/src/main/res/values-pt-rBR/strings.xml
View file @
d4d4f52c
...
...
@@ -107,6 +107,10 @@
<string
name=
"msg_image_saved_successfully"
>
Imagem salva na galeria
</string>
<string
name=
"msg_image_saved_failed"
>
Falha ao salvar a imagem
</string>
<string
name=
"msg_edited"
>
(editado)
</string>
<string
name=
"msg_and"
>
\u0020e\u0020
</string>
<string
name=
"msg_is_typing"
>
\u0020está digitando…
</string>
<string
name=
"msg_are_typing"
>
\u0020estão digitando…
</string>
<string
name=
"msg_several_users_are_typing"
>
Vários usuários estão digitando…
</string>
<string
name=
"msg_no_search_found"
>
nenhum resultado encontrado
</string>
<!-- System messages -->
...
...
app/src/main/res/values/strings.xml
View file @
d4d4f52c
...
...
@@ -108,6 +108,10 @@
<string
name=
"msg_image_saved_successfully"
>
Image has been saved to gallery
</string>
<string
name=
"msg_image_saved_failed"
>
Failed to save image
</string>
<string
name=
"msg_edited"
>
(edited)
</string>
<string
name=
"msg_and"
>
\u0020and\u0020
</string>
<string
name=
"msg_is_typing"
>
\u0020is typing…
</string>
<string
name=
"msg_are_typing"
>
\u0020are typing…
</string>
<string
name=
"msg_several_users_are_typing"
>
Several users are typing…
</string>
<string
name=
"msg_no_search_found"
>
No result found
</string>
<!-- System messages -->
...
...
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