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
73d09b24
Unverified
Commit
73d09b24
authored
Apr 23, 2018
by
Filipe de Lima Brito
Committed by
GitHub
Apr 23, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1108 from RocketChat/new/active-users
[NEW] Show user status in the chat list.
parents
3e457b9d
0b789dc0
Changes
30
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
651 additions
and
278 deletions
+651
-278
build.gradle
app/build.gradle
+2
-6
DrawableHelper.kt
app/src/main/java/chat/rocket/android/app/DrawableHelper.kt
+5
-11
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+1
-1
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+203
-63
ChatRoomsAdapter.kt
...java/chat/rocket/android/chatrooms/ui/ChatRoomsAdapter.kt
+27
-20
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+5
-5
AppModule.kt
.../main/java/chat/rocket/android/dagger/module/AppModule.kt
+26
-9
MainPresenter.kt
...va/chat/rocket/android/main/presentation/MainPresenter.kt
+3
-3
MainActivity.kt
...src/main/java/chat/rocket/android/main/ui/MainActivity.kt
+1
-4
ActiveUsersRepository.kt
...hat/rocket/android/server/domain/ActiveUsersRepository.kt
+10
-0
GetActiveUsersInteractor.kt
.../rocket/android/server/domain/GetActiveUsersInteractor.kt
+23
-0
GetChatRoomsInteractor.kt
...at/rocket/android/server/domain/GetChatRoomsInteractor.kt
+45
-6
SaveActiveUsersInteractor.kt
...rocket/android/server/domain/SaveActiveUsersInteractor.kt
+44
-0
ConnectionManager.kt
...ocket/android/server/infraestructure/ConnectionManager.kt
+23
-3
MemoryActiveUsersRepository.kt
...oid/server/infraestructure/MemoryActiveUsersRepository.kt
+15
-0
ic_hashtag_12dp.xml
app/src/main/res/drawable/ic_hashtag_12dp.xml
+30
-0
ic_lock_12_dp.xml
app/src/main/res/drawable/ic_lock_12_dp.xml
+18
-0
ic_status_away_12dp.xml
app/src/main/res/drawable/ic_status_away_12dp.xml
+13
-0
ic_status_busy_12dp.xml
app/src/main/res/drawable/ic_status_busy_12dp.xml
+13
-0
ic_status_invisible_12dp.xml
app/src/main/res/drawable/ic_status_invisible_12dp.xml
+13
-0
ic_status_online_12dp.xml
app/src/main/res/drawable/ic_status_online_12dp.xml
+13
-0
user_status_white.xml
app/src/main/res/drawable/user_status_white.xml
+0
-12
fragment_chat_rooms.xml
app/src/main/res/layout/fragment_chat_rooms.xml
+5
-4
item_change_status.xml
app/src/main/res/layout/item_change_status.xml
+4
-4
item_chat.xml
app/src/main/res/layout/item_chat.xml
+30
-22
nav_header.xml
app/src/main/res/layout/nav_header.xml
+2
-2
suggestion_member_item.xml
app/src/main/res/layout/suggestion_member_item.xml
+42
-61
suggestion_room_item.xml
app/src/main/res/layout/suggestion_room_item.xml
+21
-34
strings.xml
app/src/main/res/values-hi-rIN/strings.xml
+10
-7
dimens.xml
app/src/main/res/values/dimens.xml
+4
-1
No files found.
app/build.gradle
View file @
73d09b24
...
@@ -13,8 +13,8 @@ android {
...
@@ -13,8 +13,8 @@ android {
applicationId
"chat.rocket.android"
applicationId
"chat.rocket.android"
minSdkVersion
21
minSdkVersion
21
targetSdkVersion
versions
.
targetSdk
targetSdkVersion
versions
.
targetSdk
versionCode
201
4
versionCode
201
5
versionName
"2.
0.4
"
versionName
"2.
1.0
"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled
true
multiDexEnabled
true
}
}
...
@@ -47,10 +47,6 @@ android {
...
@@ -47,10 +47,6 @@ android {
packagingOptions
{
packagingOptions
{
exclude
'META-INF/core.kotlin_module'
exclude
'META-INF/core.kotlin_module'
}
}
lintOptions
{
disable
'MissingTranslation'
}
}
}
dependencies
{
dependencies
{
...
...
app/src/main/java/chat/rocket/android/app/DrawableHelper.kt
View file @
73d09b24
...
@@ -108,18 +108,12 @@ object DrawableHelper {
...
@@ -108,18 +108,12 @@ object DrawableHelper {
* @see [UserStatus]
* @see [UserStatus]
* @return The user status drawable.
* @return The user status drawable.
*/
*/
fun
getUserStatusDrawable
(
userStatus
:
UserStatus
,
context
:
Context
):
Drawable
{
fun
getUserStatusDrawable
(
userStatus
:
UserStatus
?
,
context
:
Context
):
Drawable
{
return
when
(
userStatus
)
{
return
when
(
userStatus
)
{
is
UserStatus
.
Online
->
{
is
UserStatus
.
Online
->
getDrawableFromId
(
R
.
drawable
.
ic_status_online_12dp
,
context
)
getDrawableFromId
(
R
.
drawable
.
ic_status_online_24dp
,
context
)
is
UserStatus
.
Away
->
getDrawableFromId
(
R
.
drawable
.
ic_status_away_12dp
,
context
)
}
is
UserStatus
.
Busy
->
getDrawableFromId
(
R
.
drawable
.
ic_status_busy_12dp
,
context
)
is
UserStatus
.
Away
->
{
else
->
getDrawableFromId
(
R
.
drawable
.
ic_status_invisible_12dp
,
context
)
getDrawableFromId
(
R
.
drawable
.
ic_status_away_24dp
,
context
)
}
is
UserStatus
.
Busy
->
{
getDrawableFromId
(
R
.
drawable
.
ic_status_busy_24dp
,
context
)
}
else
->
getDrawableFromId
(
R
.
drawable
.
ic_status_invisible_24dp
,
context
)
}
}
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
73d09b24
...
@@ -510,7 +510,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
...
@@ -510,7 +510,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
fun
loadChatRooms
()
{
fun
loadChatRooms
()
{
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
try
{
try
{
val
chatRooms
=
getChatRoomsInteractor
.
get
(
currentServer
)
val
chatRooms
=
getChatRoomsInteractor
.
get
All
(
currentServer
)
.
filterNot
{
.
filterNot
{
it
.
type
is
RoomType
.
DirectMessage
||
it
.
type
is
RoomType
.
Livechat
it
.
type
is
RoomType
.
DirectMessage
||
it
.
type
is
RoomType
.
Livechat
}
}
...
...
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
73d09b24
...
@@ -18,6 +18,7 @@ import chat.rocket.common.model.BaseRoom
...
@@ -18,6 +18,7 @@ import chat.rocket.common.model.BaseRoom
import
chat.rocket.common.model.RoomType
import
chat.rocket.common.model.RoomType
import
chat.rocket.common.model.SimpleUser
import
chat.rocket.common.model.SimpleUser
import
chat.rocket.common.model.User
import
chat.rocket.common.model.User
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.internal.model.Subscription
import
chat.rocket.core.internal.model.Subscription
import
chat.rocket.core.internal.realtime.socket.model.State
import
chat.rocket.core.internal.realtime.socket.model.State
import
chat.rocket.core.internal.realtime.socket.model.StreamMessage
import
chat.rocket.core.internal.realtime.socket.model.StreamMessage
...
@@ -32,26 +33,29 @@ import timber.log.Timber
...
@@ -32,26 +33,29 @@ import timber.log.Timber
import
javax.inject.Inject
import
javax.inject.Inject
import
kotlin.reflect.KProperty1
import
kotlin.reflect.KProperty1
class
ChatRoomsPresenter
@Inject
constructor
(
private
val
view
:
ChatRoomsView
,
class
ChatRoomsPresenter
@Inject
constructor
(
private
val
strategy
:
CancelStrategy
,
private
val
view
:
ChatRoomsView
,
private
val
navigator
:
MainNavigator
,
private
val
strategy
:
CancelStrategy
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
navigator
:
MainNavigator
,
private
val
getChatRoomsInteractor
:
GetChatRoomsInteractor
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
saveChatRoomsInteractor
:
SaveChatRoomsInteractor
,
private
val
getChatRoomsInteractor
:
GetChatRoomsInteractor
,
private
val
refreshSettingsInteractor
:
RefreshSettingsInteractor
,
private
val
saveChatRoomsInteractor
:
SaveChatRoomsInteractor
,
private
val
viewModelMapper
:
ViewModelMapper
,
private
val
saveActiveUsersInteractor
:
SaveActiveUsersInteractor
,
private
val
jobSchedulerInteractor
:
JobSchedulerInteractor
,
private
val
getActiveUsersInteractor
:
GetActiveUsersInteractor
,
settingsRepository
:
SettingsRepository
,
private
val
refreshSettingsInteractor
:
RefreshSettingsInteractor
,
factory
:
ConnectionManagerFactory
)
{
private
val
viewModelMapper
:
ViewModelMapper
,
private
val
jobSchedulerInteractor
:
JobSchedulerInteractor
,
settingsRepository
:
SettingsRepository
,
factory
:
ConnectionManagerFactory
)
{
private
val
manager
:
ConnectionManager
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
manager
:
ConnectionManager
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
client
=
manager
.
client
private
val
client
=
manager
.
client
private
var
reloadJob
:
Deferred
<
List
<
ChatRoom
>>?
=
null
private
var
reloadJob
:
Deferred
<
List
<
ChatRoom
>>?
=
null
private
val
settings
=
settingsRepository
.
get
(
currentServer
)
private
val
settings
=
settingsRepository
.
get
(
currentServer
)
private
val
subscriptionsChannel
=
Channel
<
StreamMessage
<
BaseRoom
>>()
private
val
stateChannel
=
Channel
<
State
>()
private
val
stateChannel
=
Channel
<
State
>()
private
val
subscriptionsChannel
=
Channel
<
StreamMessage
<
BaseRoom
>>()
private
val
activeUserChannel
=
Channel
<
User
>()
private
var
lastState
=
manager
.
state
private
var
lastState
=
manager
.
state
fun
loadChatRooms
()
{
fun
loadChatRooms
()
{
...
@@ -60,13 +64,18 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -60,13 +64,18 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
view
.
showLoading
()
view
.
showLoading
()
subscribeStatusChange
()
subscribeStatusChange
()
try
{
try
{
view
.
updateChatRooms
(
loadRooms
())
view
.
updateChatRooms
(
getUserChatRooms
())
}
catch
(
e
:
RocketChatException
)
{
}
catch
(
ex
:
RocketChatException
)
{
Timber
.
e
(
e
)
ex
.
message
?.
let
{
view
.
showMessage
(
e
.
message
!!
)
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
Timber
.
e
(
ex
)
}
finally
{
}
finally
{
view
.
hideLoading
()
view
.
hideLoading
()
}
}
subscribeActiveUsers
()
subscribeRoomUpdates
()
subscribeRoomUpdates
()
}
}
}
}
...
@@ -94,7 +103,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -94,7 +103,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
val
currentServer
=
serverInteractor
.
get
()
!!
val
currentServer
=
serverInteractor
.
get
()
!!
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
try
{
try
{
val
roomList
=
getChatRoomsInteractor
.
getByName
(
currentServer
,
name
)
val
roomList
=
getChatRoomsInteractor
.
get
All
ByName
(
currentServer
,
name
)
if
(
roomList
.
isEmpty
())
{
if
(
roomList
.
isEmpty
())
{
val
(
users
,
rooms
)
=
retryIO
(
"spotlight($name)"
)
{
val
(
users
,
rooms
)
=
retryIO
(
"spotlight($name)"
)
{
client
.
spotlight
(
name
)
client
.
spotlight
(
name
)
...
@@ -102,9 +111,13 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -102,9 +111,13 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
val
chatRoomsCombined
=
mutableListOf
<
ChatRoom
>()
val
chatRoomsCombined
=
mutableListOf
<
ChatRoom
>()
chatRoomsCombined
.
addAll
(
usersToChatRooms
(
users
))
chatRoomsCombined
.
addAll
(
usersToChatRooms
(
users
))
chatRoomsCombined
.
addAll
(
roomsToChatRooms
(
rooms
))
chatRoomsCombined
.
addAll
(
roomsToChatRooms
(
rooms
))
view
.
updateChatRooms
(
getChatRoomsWithPreviews
(
chatRoomsCombined
.
toList
()))
val
chatRoomsWithPreview
=
getChatRoomsWithPreviews
(
chatRoomsCombined
)
val
chatRoomsWithStatus
=
getChatRoomWithStatus
(
chatRoomsWithPreview
)
view
.
updateChatRooms
(
chatRoomsWithStatus
)
}
else
{
}
else
{
view
.
updateChatRooms
(
getChatRoomsWithPreviews
(
roomList
))
val
chatRoomsWithPreview
=
getChatRoomsWithPreviews
(
roomList
)
val
chatRoomsWithStatus
=
getChatRoomWithStatus
(
chatRoomsWithPreview
)
view
.
updateChatRooms
(
chatRoomsWithStatus
)
}
}
}
catch
(
ex
:
RocketChatException
)
{
}
catch
(
ex
:
RocketChatException
)
{
Timber
.
e
(
ex
)
Timber
.
e
(
ex
)
...
@@ -112,13 +125,32 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -112,13 +125,32 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
}
}
}
private
suspend
fun
usersToChatRooms
(
users
:
List
<
User
>):
List
<
ChatRoom
>
{
// In the first time it will not come with the users status, but after called by the
// [reloadRooms] function may be with.
private
suspend
fun
getUserChatRooms
():
List
<
ChatRoom
>
{
val
chatRooms
=
retryIO
(
"chatRooms"
)
{
manager
.
chatRooms
().
update
}
val
chatRoomsWithPreview
=
getChatRoomsWithPreviews
(
chatRooms
)
val
chatRoomsWithUserStatus
=
getChatRoomWithStatus
(
chatRoomsWithPreview
)
val
sortedRooms
=
sortRooms
(
chatRoomsWithUserStatus
)
Timber
.
d
(
"Loaded rooms: ${sortedRooms.size}"
)
saveChatRoomsInteractor
.
save
(
currentServer
,
sortedRooms
)
return
sortedRooms
}
private
fun
usersToChatRooms
(
users
:
List
<
User
>):
List
<
ChatRoom
>
{
return
users
.
map
{
return
users
.
map
{
ChatRoom
(
id
=
it
.
id
,
ChatRoom
(
id
=
it
.
id
,
type
=
RoomType
.
DIRECT_MESSAGE
,
type
=
RoomType
.
DIRECT_MESSAGE
,
user
=
SimpleUser
(
username
=
it
.
username
,
name
=
it
.
name
,
id
=
null
),
user
=
SimpleUser
(
username
=
it
.
username
,
name
=
it
.
name
,
id
=
null
),
status
=
if
(
it
.
name
!=
null
)
{
getActiveUsersInteractor
.
getActiveUserByUsername
(
currentServer
,
it
.
name
!!
)
?.
status
}
else
{
null
},
name
=
it
.
name
?:
""
,
name
=
it
.
name
?:
""
,
status
=
null
,
fullName
=
it
.
name
,
fullName
=
it
.
name
,
readonly
=
false
,
readonly
=
false
,
updatedAt
=
null
,
updatedAt
=
null
,
...
@@ -139,13 +171,19 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -139,13 +171,19 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
}
}
}
private
suspend
fun
roomsToChatRooms
(
rooms
:
List
<
Room
>):
List
<
ChatRoom
>
{
private
fun
roomsToChatRooms
(
rooms
:
List
<
Room
>):
List
<
ChatRoom
>
{
return
rooms
.
map
{
return
rooms
.
map
{
ChatRoom
(
id
=
it
.
id
,
ChatRoom
(
id
=
it
.
id
,
type
=
it
.
type
,
type
=
it
.
type
,
user
=
it
.
user
,
user
=
it
.
user
,
status
=
if
(
it
.
name
!=
null
)
{
getActiveUsersInteractor
.
getActiveUserByUsername
(
currentServer
,
it
.
name
!!
)
?.
status
}
else
{
null
},
name
=
it
.
name
?:
""
,
name
=
it
.
name
?:
""
,
status
=
null
,
fullName
=
it
.
fullName
,
fullName
=
it
.
fullName
,
readonly
=
it
.
readonly
,
readonly
=
it
.
readonly
,
updatedAt
=
it
.
updatedAt
,
updatedAt
=
it
.
updatedAt
,
...
@@ -166,18 +204,9 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -166,18 +204,9 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
}
}
}
private
suspend
fun
loadRooms
():
List
<
ChatRoom
>
{
val
chatRooms
=
retryIO
(
"chatRooms"
)
{
manager
.
chatRooms
().
update
}
val
sortedRooms
=
sortRooms
(
chatRooms
)
Timber
.
d
(
"Loaded rooms: ${sortedRooms.size}"
)
saveChatRoomsInteractor
.
save
(
currentServer
,
sortedRooms
)
return
getChatRoomsWithPreviews
(
sortedRooms
)
}
fun
updateSortedChatRooms
()
{
fun
updateSortedChatRooms
()
{
val
currentServer
=
serverInteractor
.
get
()
!!
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
val
roomList
=
getChatRoomsInteractor
.
get
(
currentServer
)
val
roomList
=
getChatRoomsInteractor
.
get
All
(
currentServer
)
view
.
updateChatRooms
(
sortRooms
(
roomList
))
view
.
updateChatRooms
(
sortRooms
(
roomList
))
}
}
}
}
...
@@ -223,11 +252,39 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -223,11 +252,39 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
}
}
}
private
fun
updateRooms
()
{
private
fun
getChatRoomWithStatus
(
chatRooms
:
List
<
ChatRoom
>):
List
<
ChatRoom
>
{
Timber
.
d
(
"Updating Rooms"
)
val
chatRoomsList
=
mutableListOf
<
ChatRoom
>()
launch
(
strategy
.
jobs
)
{
chatRooms
.
forEach
{
view
.
updateChatRooms
(
getChatRoomsWithPreviews
(
getChatRoomsInteractor
.
get
(
currentServer
)))
val
newRoom
=
ChatRoom
(
id
=
it
.
id
,
type
=
it
.
type
,
user
=
it
.
user
,
status
=
getActiveUsersInteractor
.
getActiveUserByUsername
(
currentServer
,
it
.
name
)
?.
status
,
name
=
it
.
name
,
fullName
=
it
.
fullName
,
readonly
=
it
.
readonly
,
updatedAt
=
it
.
updatedAt
,
timestamp
=
it
.
timestamp
,
lastSeen
=
it
.
lastSeen
,
topic
=
it
.
topic
,
description
=
it
.
description
,
announcement
=
it
.
announcement
,
default
=
it
.
default
,
favorite
=
it
.
favorite
,
open
=
it
.
open
,
alert
=
it
.
alert
,
unread
=
it
.
unread
,
userMenstions
=
it
.
userMenstions
,
groupMentions
=
it
.
groupMentions
,
lastMessage
=
it
.
lastMessage
,
client
=
client
)
chatRoomsList
.
add
(
newRoom
)
}
}
return
chatRoomsList
}
}
private
suspend
fun
getChatRoomsWithPreviews
(
chatRooms
:
List
<
ChatRoom
>):
List
<
ChatRoom
>
{
private
suspend
fun
getChatRoomsWithPreviews
(
chatRooms
:
List
<
ChatRoom
>):
List
<
ChatRoom
>
{
...
@@ -244,12 +301,6 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -244,12 +301,6 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
return
chatRooms
.
filter
(
ChatRoom
::
open
)
return
chatRooms
.
filter
(
ChatRoom
::
open
)
}
}
private
fun
sortChatRooms
(
chatRooms
:
List
<
ChatRoom
>):
List
<
ChatRoom
>
{
return
chatRooms
.
sortedByDescending
{
chatRoom
->
chatRoom
.
lastMessage
?.
timestamp
}
}
private
suspend
fun
subscribeStatusChange
()
{
private
suspend
fun
subscribeStatusChange
()
{
lastState
=
manager
.
state
lastState
=
manager
.
state
launch
(
CommonPool
+
strategy
.
jobs
)
{
launch
(
CommonPool
+
strategy
.
jobs
)
{
...
@@ -259,11 +310,10 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -259,11 +310,10 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
launch
(
UI
)
{
launch
(
UI
)
{
view
.
showConnectionState
(
state
)
view
.
showConnectionState
(
state
)
}
}
if
(
state
is
State
.
Connected
)
{
if
(
state
is
State
.
Connected
)
{
jobSchedulerInteractor
.
scheduleSendingMessages
()
jobSchedulerInteractor
.
scheduleSendingMessages
()
reloadRooms
()
reloadRooms
()
updateRooms
()
update
Chat
Rooms
()
}
}
}
}
lastState
=
state
lastState
=
state
...
@@ -303,7 +353,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -303,7 +353,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
}
}
}
updateRooms
()
update
Chat
Rooms
()
}
}
private
suspend
fun
updateSubscription
(
message
:
StreamMessage
<
Subscription
>)
{
private
suspend
fun
updateSubscription
(
message
:
StreamMessage
<
Subscription
>)
{
...
@@ -322,7 +372,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -322,7 +372,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
}
}
}
updateRooms
()
update
Chat
Rooms
()
}
}
private
suspend
fun
reloadRooms
()
{
private
suspend
fun
reloadRooms
()
{
...
@@ -333,7 +383,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -333,7 +383,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
reloadJob
=
async
(
CommonPool
+
strategy
.
jobs
)
{
reloadJob
=
async
(
CommonPool
+
strategy
.
jobs
)
{
delay
(
1000
)
delay
(
1000
)
Timber
.
d
(
"reloading rooms after wait"
)
Timber
.
d
(
"reloading rooms after wait"
)
load
Rooms
()
getUserChat
Rooms
()
}
}
reloadJob
?.
await
()
reloadJob
?.
await
()
}
catch
(
ex
:
Exception
)
{
}
catch
(
ex
:
Exception
)
{
...
@@ -344,14 +394,18 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -344,14 +394,18 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
// Update a ChatRoom with a Room information
// Update a ChatRoom with a Room information
private
fun
updateRoom
(
room
:
Room
)
{
private
fun
updateRoom
(
room
:
Room
)
{
Timber
.
d
(
"Updating Room: ${room.id} - ${room.name}"
)
Timber
.
d
(
"Updating Room: ${room.id} - ${room.name}"
)
val
chatRooms
=
getChatRoomsInteractor
.
get
(
currentServer
).
toMutableList
()
val
chatRooms
=
getChatRoomsInteractor
.
get
All
(
currentServer
).
toMutableList
()
val
chatRoom
=
chatRooms
.
find
{
chatRoom
->
chatRoom
.
id
==
room
.
id
}
val
chatRoom
=
chatRooms
.
find
{
chatRoom
->
chatRoom
.
id
==
room
.
id
}
chatRoom
?.
apply
{
chatRoom
?.
apply
{
val
newRoom
=
ChatRoom
(
id
=
room
.
id
,
val
newRoom
=
ChatRoom
(
id
=
room
.
id
,
type
=
room
.
type
,
type
=
room
.
type
,
user
=
room
.
user
?:
user
,
user
=
room
.
user
?:
user
,
status
=
getActiveUsersInteractor
.
getActiveUserByUsername
(
currentServer
,
room
.
name
?:
name
)
?.
status
,
name
=
room
.
name
?:
name
,
name
=
room
.
name
?:
name
,
status
=
null
,
fullName
=
room
.
fullName
?:
fullName
,
fullName
=
room
.
fullName
?:
fullName
,
readonly
=
room
.
readonly
,
readonly
=
room
.
readonly
,
updatedAt
=
room
.
updatedAt
?:
updatedAt
,
updatedAt
=
room
.
updatedAt
?:
updatedAt
,
...
@@ -368,7 +422,8 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -368,7 +422,8 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
userMenstions
=
userMenstions
,
userMenstions
=
userMenstions
,
groupMentions
=
groupMentions
,
groupMentions
=
groupMentions
,
lastMessage
=
room
.
lastMessage
,
lastMessage
=
room
.
lastMessage
,
client
=
client
)
client
=
client
)
removeRoom
(
room
.
id
,
chatRooms
)
removeRoom
(
room
.
id
,
chatRooms
)
chatRooms
.
add
(
newRoom
)
chatRooms
.
add
(
newRoom
)
saveChatRoomsInteractor
.
save
(
currentServer
,
sortRooms
(
chatRooms
))
saveChatRoomsInteractor
.
save
(
currentServer
,
sortRooms
(
chatRooms
))
...
@@ -378,14 +433,18 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -378,14 +433,18 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
// Update a ChatRoom with a Subscription information
// Update a ChatRoom with a Subscription information
private
fun
updateSubscription
(
subscription
:
Subscription
)
{
private
fun
updateSubscription
(
subscription
:
Subscription
)
{
Timber
.
d
(
"Updating subscription: ${subscription.id} - ${subscription.name}"
)
Timber
.
d
(
"Updating subscription: ${subscription.id} - ${subscription.name}"
)
val
chatRooms
=
getChatRoomsInteractor
.
get
(
currentServer
).
toMutableList
()
val
chatRooms
=
getChatRoomsInteractor
.
get
All
(
currentServer
).
toMutableList
()
val
chatRoom
=
chatRooms
.
find
{
chatRoom
->
chatRoom
.
id
==
subscription
.
roomId
}
val
chatRoom
=
chatRooms
.
find
{
chatRoom
->
chatRoom
.
id
==
subscription
.
roomId
}
chatRoom
?.
apply
{
chatRoom
?.
apply
{
val
newRoom
=
ChatRoom
(
id
=
subscription
.
roomId
,
val
newRoom
=
ChatRoom
(
id
=
subscription
.
roomId
,
type
=
subscription
.
type
,
type
=
subscription
.
type
,
user
=
subscription
.
user
?:
user
,
user
=
subscription
.
user
?:
user
,
status
=
getActiveUsersInteractor
.
getActiveUserByUsername
(
currentServer
,
subscription
.
name
)
?.
status
,
name
=
subscription
.
name
,
name
=
subscription
.
name
,
status
=
null
,
fullName
=
subscription
.
fullName
?:
fullName
,
fullName
=
subscription
.
fullName
?:
fullName
,
readonly
=
subscription
.
readonly
?:
readonly
,
readonly
=
subscription
.
readonly
?:
readonly
,
updatedAt
=
subscription
.
updatedAt
?:
updatedAt
,
updatedAt
=
subscription
.
updatedAt
?:
updatedAt
,
...
@@ -402,16 +461,18 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -402,16 +461,18 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
userMenstions
=
subscription
.
userMentions
,
userMenstions
=
subscription
.
userMentions
,
groupMentions
=
subscription
.
groupMentions
,
groupMentions
=
subscription
.
groupMentions
,
lastMessage
=
lastMessage
,
lastMessage
=
lastMessage
,
client
=
client
)
client
=
client
)
removeRoom
(
subscription
.
roomId
,
chatRooms
)
removeRoom
(
subscription
.
roomId
,
chatRooms
)
chatRooms
.
add
(
newRoom
)
chatRooms
.
add
(
newRoom
)
saveChatRoomsInteractor
.
save
(
currentServer
,
sortRooms
(
chatRooms
))
saveChatRoomsInteractor
.
save
(
currentServer
,
sortRooms
(
chatRooms
))
}
}
}
}
private
fun
removeRoom
(
private
fun
removeRoom
(
id
:
String
,
id
:
String
,
chatRooms
:
MutableList
<
ChatRoom
>
=
getChatRoomsInteractor
.
get
(
currentServer
).
toMutableList
())
{
chatRooms
:
MutableList
<
ChatRoom
>
=
getChatRoomsInteractor
.
getAll
(
currentServer
).
toMutableList
()
)
{
Timber
.
d
(
"Removing ROOM: $id"
)
Timber
.
d
(
"Removing ROOM: $id"
)
synchronized
(
this
)
{
synchronized
(
this
)
{
chatRooms
.
removeAll
{
chatRoom
->
chatRoom
.
id
==
id
}
chatRooms
.
removeAll
{
chatRoom
->
chatRoom
.
id
==
id
}
...
@@ -419,8 +480,87 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
...
@@ -419,8 +480,87 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
saveChatRoomsInteractor
.
save
(
currentServer
,
sortRooms
(
chatRooms
))
saveChatRoomsInteractor
.
save
(
currentServer
,
sortRooms
(
chatRooms
))
}
}
private
suspend
fun
subscribeActiveUsers
()
{
manager
.
addActiveUserChannel
(
activeUserChannel
)
launch
(
CommonPool
+
strategy
.
jobs
)
{
for
(
user
in
activeUserChannel
)
{
processActiveUser
(
user
)
}
}
}
private
fun
processActiveUser
(
user
:
User
)
{
// The first activeUsers stream contains all details of the users (username, UTC Offset,
// etc.), so we add each user to our [saveActiveUsersInteractor] class because the following
// streams don't contain those details.
if
(!
getActiveUsersInteractor
.
isActiveUserOnRepository
(
currentServer
,
user
))
{
Timber
.
d
(
"Got first active user stream for the user: $user"
)
saveActiveUsersInteractor
.
addActiveUser
(
currentServer
,
user
)
}
else
{
// After the first stream the next is about the active users updates.
Timber
.
d
(
"Got update of active user stream for the user: $user"
)
saveActiveUsersInteractor
.
updateActiveUser
(
currentServer
,
user
)
}
getActiveUsersInteractor
.
getActiveUserById
(
currentServer
,
user
.
id
)
?.
let
{
updateChatRoomWithUserStatus
(
it
)
}
}
private
fun
updateChatRoomWithUserStatus
(
user_
:
User
)
{
Timber
.
d
(
"active User: $user_"
)
val
username
=
user_
.
username
val
status
=
user_
.
status
if
(
username
!=
null
&&
status
!=
null
)
{
getChatRoomsInteractor
.
getByName
(
currentServer
,
username
)
?.
let
{
val
newRoom
=
ChatRoom
(
id
=
it
.
id
,
type
=
it
.
type
,
user
=
it
.
user
,
status
=
status
,
name
=
it
.
name
,
fullName
=
it
.
fullName
,
readonly
=
it
.
readonly
,
updatedAt
=
it
.
updatedAt
,
timestamp
=
it
.
timestamp
,
lastSeen
=
it
.
lastSeen
,
topic
=
it
.
topic
,
description
=
it
.
description
,
announcement
=
it
.
announcement
,
default
=
it
.
default
,
favorite
=
it
.
favorite
,
open
=
it
.
open
,
alert
=
it
.
alert
,
unread
=
it
.
unread
,
userMenstions
=
it
.
userMenstions
,
groupMentions
=
it
.
groupMentions
,
lastMessage
=
it
.
lastMessage
,
client
=
client
)
getChatRoomsInteractor
.
remove
(
currentServer
,
it
)
getChatRoomsInteractor
.
add
(
currentServer
,
newRoom
)
launchUI
(
strategy
)
{
view
.
updateChatRooms
(
sortRooms
(
getChatRoomsInteractor
.
getAll
(
currentServer
)))
}
}
}
}
private
fun
updateChatRooms
()
{
Timber
.
i
(
"Updating ChatRooms"
)
launch
(
strategy
.
jobs
)
{
val
chatRoomsWithPreview
=
getChatRoomsWithPreviews
(
getChatRoomsInteractor
.
getAll
(
currentServer
)
)
val
chatRoomsWithStatus
=
getChatRoomWithStatus
(
chatRoomsWithPreview
)
view
.
updateChatRooms
(
chatRoomsWithStatus
)
}
}
fun
disconnect
()
{
fun
disconnect
()
{
manager
.
removeStatusChannel
(
stateChannel
)
manager
.
removeStatusChannel
(
stateChannel
)
manager
.
removeRoomsAndSubscriptionsChannel
(
subscriptionsChannel
)
manager
.
removeRoomsAndSubscriptionsChannel
(
subscriptionsChannel
)
manager
.
removeActiveUserChannel
(
activeUserChannel
)
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsAdapter.kt
View file @
73d09b24
...
@@ -10,6 +10,7 @@ import android.text.SpannableStringBuilder
...
@@ -10,6 +10,7 @@ import android.text.SpannableStringBuilder
import
android.text.style.ForegroundColorSpan
import
android.text.style.ForegroundColorSpan
import
android.view.View
import
android.view.View
import
android.view.ViewGroup
import
android.view.ViewGroup
import
android.widget.ImageView
import
android.widget.TextView
import
android.widget.TextView
import
chat.rocket.android.R
import
chat.rocket.android.R
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.LocalRepository
...
@@ -49,6 +50,7 @@ class ChatRoomsAdapter(private val context: Context,
...
@@ -49,6 +50,7 @@ class ChatRoomsAdapter(private val context: Context,
fun
bind
(
chatRoom
:
ChatRoom
)
=
with
(
itemView
)
{
fun
bind
(
chatRoom
:
ChatRoom
)
=
with
(
itemView
)
{
bindAvatar
(
chatRoom
,
image_avatar
)
bindAvatar
(
chatRoom
,
image_avatar
)
bindName
(
chatRoom
,
text_chat_name
)
bindName
(
chatRoom
,
text_chat_name
)
bindIcon
(
chatRoom
,
image_chat_icon
)
bindLastMessageDateTime
(
chatRoom
,
text_last_message_date_time
)
bindLastMessageDateTime
(
chatRoom
,
text_last_message_date_time
)
bindLastMessage
(
chatRoom
,
text_last_message
)
bindLastMessage
(
chatRoom
,
text_last_message
)
bindUnreadMessages
(
chatRoom
,
text_total_unread_messages
)
bindUnreadMessages
(
chatRoom
,
text_total_unread_messages
)
...
@@ -80,34 +82,39 @@ class ChatRoomsAdapter(private val context: Context,
...
@@ -80,34 +82,39 @@ class ChatRoomsAdapter(private val context: Context,
}
}
}
}
private
fun
bindName
(
chatRoom
:
ChatRoom
,
textView
:
TextView
)
{
private
fun
bindIcon
(
chatRoom
:
ChatRoom
,
imageView
:
ImageView
)
{
textView
.
textContent
=
chatRoom
.
name
val
drawable
=
when
(
chatRoom
.
type
)
{
val
drawable
=
when
(
chatRoom
.
type
)
{
is
RoomType
.
Channel
->
{
is
RoomType
.
Channel
->
DrawableHelper
.
getDrawableFromId
(
DrawableHelper
.
getDrawableFromId
(
R
.
drawable
.
ic_room_channel
,
context
)
R
.
drawable
.
ic_hashtag_12dp
,
}
context
is
RoomType
.
PrivateGroup
->
{
)
DrawableHelper
.
getDrawableFromId
(
R
.
drawable
.
ic_room_lock
,
context
)
is
RoomType
.
PrivateGroup
->
DrawableHelper
.
getDrawableFromId
(
}
R
.
drawable
.
ic_lock_12_dp
,
is
RoomType
.
DirectMessage
->
{
context
DrawableHelper
.
getDrawableFromId
(
R
.
drawable
.
ic_room_dm
,
context
)
)
}
is
RoomType
.
DirectMessage
->
DrawableHelper
.
getUserStatusDrawable
(
chatRoom
.
status
,
context
)
else
->
null
else
->
null
}
}
drawable
?.
let
{
drawable
?.
let
{
val
wrappedDrawable
=
DrawableHelper
.
wrapDrawable
(
it
)
val
mutateDrawable
=
DrawableHelper
.
wrapDrawable
(
it
).
mutate
()
val
mutableDrawable
=
wrappedDrawable
.
mutate
()
if
(
chatRoom
.
type
!
is
RoomType
.
DirectMessage
)
{
val
color
=
when
(
chatRoom
.
alert
||
chatRoom
.
unread
>
0
)
{
val
color
=
when
(
chatRoom
.
alert
||
chatRoom
.
unread
>
0
)
{
true
->
R
.
color
.
colorPrimaryText
true
->
R
.
color
.
colorPrimaryText
false
->
R
.
color
.
colorSecondaryText
false
->
R
.
color
.
colorSecondaryText
}
DrawableHelper
.
tintDrawable
(
mutateDrawable
,
context
,
color
)
}
}
DrawableHelper
.
tintDrawable
(
mutableDrawable
,
context
,
color
)
imageView
.
setImageDrawable
(
mutateDrawable
)
DrawableHelper
.
compoundDrawable
(
textView
,
mutableDrawable
)
}
}
}
}
private
fun
bindName
(
chatRoom
:
ChatRoom
,
textView
:
TextView
)
{
textView
.
textContent
=
chatRoom
.
name
}
private
fun
bindLastMessageDateTime
(
chatRoom
:
ChatRoom
,
textView
:
TextView
)
{
private
fun
bindLastMessageDateTime
(
chatRoom
:
ChatRoom
,
textView
:
TextView
)
{
val
lastMessage
=
chatRoom
.
lastMessage
val
lastMessage
=
chatRoom
.
lastMessage
if
(
lastMessage
!=
null
)
{
if
(
lastMessage
!=
null
)
{
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
73d09b24
...
@@ -32,12 +32,9 @@ import dagger.android.support.AndroidSupportInjection
...
@@ -32,12 +32,9 @@ 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.Job
import
kotlinx.coroutines.experimental.Job
import
kotlinx.coroutines.experimental.NonCancellable.isActive
import
kotlinx.coroutines.experimental.NonCancellable.isActive
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.launch
import
timber.log.Timber
import
timber.log.Timber
import
javax.inject.Inject
import
javax.inject.Inject
class
ChatRoomsFragment
:
Fragment
(),
ChatRoomsView
{
class
ChatRoomsFragment
:
Fragment
(),
ChatRoomsView
{
@Inject
lateinit
var
presenter
:
ChatRoomsPresenter
@Inject
lateinit
var
presenter
:
ChatRoomsPresenter
@Inject
lateinit
var
serverInteractor
:
GetCurrentServerInteractor
@Inject
lateinit
var
serverInteractor
:
GetCurrentServerInteractor
...
@@ -67,7 +64,11 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
...
@@ -67,7 +64,11 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
super
.
onDestroy
()
super
.
onDestroy
()
}
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
container
?.
inflate
(
R
.
layout
.
fragment_chat_rooms
)
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?
):
View
?
=
container
?.
inflate
(
R
.
layout
.
fragment_chat_rooms
)
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
super
.
onViewCreated
(
view
,
savedInstanceState
)
...
@@ -100,7 +101,6 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
...
@@ -100,7 +101,6 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
})
})
}
}
override
fun
onOptionsItemSelected
(
item
:
MenuItem
):
Boolean
{
override
fun
onOptionsItemSelected
(
item
:
MenuItem
):
Boolean
{
when
(
item
.
itemId
)
{
when
(
item
.
itemId
)
{
R
.
id
.
action_sort
->
{
R
.
id
.
action_sort
->
{
...
...
app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt
View file @
73d09b24
...
@@ -22,6 +22,8 @@ import chat.rocket.android.infrastructure.LocalRepository
...
@@ -22,6 +22,8 @@ import chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.SharedPrefsLocalRepository
import
chat.rocket.android.infrastructure.SharedPrefsLocalRepository
import
chat.rocket.android.push.GroupedPush
import
chat.rocket.android.push.GroupedPush
import
chat.rocket.android.push.PushManager
import
chat.rocket.android.push.PushManager
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.infraestructure.*
import
chat.rocket.android.server.domain.AccountsRepository
import
chat.rocket.android.server.domain.AccountsRepository
import
chat.rocket.android.server.domain.ChatRoomsRepository
import
chat.rocket.android.server.domain.ChatRoomsRepository
import
chat.rocket.android.server.domain.CurrentServerRepository
import
chat.rocket.android.server.domain.CurrentServerRepository
...
@@ -230,17 +232,32 @@ class AppModule {
...
@@ -230,17 +232,32 @@ class AppModule {
@Provides
@Provides
@Singleton
@Singleton
fun
provideMoshi
(
logger
:
PlatformLogger
,
fun
provideActiveUsersRepository
():
ActiveUsersRepository
{
currentServerInteractor
:
GetCurrentServerInteractor
):
return
MemoryActiveUsersRepository
()
Moshi
{
}
@Provides
@Singleton
fun
provideMoshi
(
logger
:
PlatformLogger
,
currentServerInteractor
:
GetCurrentServerInteractor
):
Moshi
{
val
url
=
currentServerInteractor
.
get
()
?:
""
val
url
=
currentServerInteractor
.
get
()
?:
""
return
Moshi
.
Builder
()
return
Moshi
.
Builder
()
.
add
(
FallbackSealedClassJsonAdapter
.
ADAPTER_FACTORY
)
.
add
(
FallbackSealedClassJsonAdapter
.
ADAPTER_FACTORY
)
.
add
(
AppJsonAdapterFactory
.
INSTANCE
)
.
add
(
AppJsonAdapterFactory
.
INSTANCE
)
.
add
(
AttachmentAdapterFactory
(
Logger
(
logger
,
url
)))
.
add
(
AttachmentAdapterFactory
(
Logger
(
logger
,
url
)))
.
add
(
java
.
lang
.
Long
::
class
.
java
,
ISO8601Date
::
class
.
java
,
TimestampAdapter
(
CalendarISO8601Converter
()))
.
add
(
.
add
(
Long
::
class
.
java
,
ISO8601Date
::
class
.
java
,
TimestampAdapter
(
CalendarISO8601Converter
()))
java
.
lang
.
Long
::
class
.
java
,
.
build
()
ISO8601Date
::
class
.
java
,
TimestampAdapter
(
CalendarISO8601Converter
())
)
.
add
(
Long
::
class
.
java
,
ISO8601Date
::
class
.
java
,
TimestampAdapter
(
CalendarISO8601Converter
())
)
.
build
()
}
}
@Provides
@Provides
...
...
app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt
View file @
73d09b24
...
@@ -186,9 +186,9 @@ class MainPresenter @Inject constructor(
...
@@ -186,9 +186,9 @@ class MainPresenter @Inject constructor(
private
suspend
fun
subscribeMyselfUpdates
()
{
private
suspend
fun
subscribeMyselfUpdates
()
{
manager
.
addUserDataChannel
(
userDataChannel
)
manager
.
addUserDataChannel
(
userDataChannel
)
for
(
myself
in
userDataChannel
)
{
for
(
myself
in
userDataChannel
)
{
updateMyself
(
myself
)
updateMyself
(
myself
)
}
}
}
}
private
suspend
fun
updateMyself
(
myself
:
Myself
)
{
private
suspend
fun
updateMyself
(
myself
:
Myself
)
{
...
...
app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt
View file @
73d09b24
...
@@ -84,10 +84,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
...
@@ -84,10 +84,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
override
fun
showUserStatus
(
userStatus
:
UserStatus
)
{
override
fun
showUserStatus
(
userStatus
:
UserStatus
)
{
headerLayout
.
apply
{
headerLayout
.
apply
{
image_user_status
.
setImageDrawable
(
image_user_status
.
setImageDrawable
(
DrawableHelper
.
getUserStatusDrawable
(
DrawableHelper
.
getUserStatusDrawable
(
userStatus
,
this
.
context
)
userStatus
,
this
.
context
)
)
)
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/server/domain/ActiveUsersRepository.kt
0 → 100644
View file @
73d09b24
package
chat.rocket.android.server.domain
import
chat.rocket.common.model.User
interface
ActiveUsersRepository
{
fun
save
(
url
:
String
,
activeUsers
:
List
<
User
>)
fun
get
(
url
:
String
):
List
<
User
>
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/GetActiveUsersInteractor.kt
0 → 100644
View file @
73d09b24
package
chat.rocket.android.server.domain
import
chat.rocket.common.model.User
import
javax.inject.Inject
class
GetActiveUsersInteractor
@Inject
constructor
(
private
val
repository
:
ActiveUsersRepository
)
{
fun
isActiveUserOnRepository
(
url
:
String
,
user
:
User
):
Boolean
{
return
repository
.
get
(
url
).
any
{
user_
->
user_
.
id
==
user
.
id
}
}
fun
getAllActiveUsers
(
url
:
String
):
List
<
User
>
{
return
repository
.
get
(
url
)
}
fun
getActiveUserById
(
url
:
String
,
id
:
String
):
User
?
{
return
repository
.
get
(
url
).
find
{
user
->
user
.
id
==
id
}
}
fun
getActiveUserByUsername
(
url
:
String
,
username
:
String
):
User
?
{
return
repository
.
get
(
url
).
find
{
user
->
user
.
username
==
username
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/GetChatRoomsInteractor.kt
View file @
73d09b24
...
@@ -8,13 +8,13 @@ import javax.inject.Inject
...
@@ -8,13 +8,13 @@ import javax.inject.Inject
class
GetChatRoomsInteractor
@Inject
constructor
(
private
val
repository
:
ChatRoomsRepository
)
{
class
GetChatRoomsInteractor
@Inject
constructor
(
private
val
repository
:
ChatRoomsRepository
)
{
/**
/**
* Get all
ChatRoom objects
.
* Get all
[ChatRoom]
.
*
*
* @param url The server url.
* @param url The server url.
*
*
* @return All the
ChatRoom
objects.
* @return All the
[ChatRoom]
objects.
*/
*/
fun
get
(
url
:
String
)
=
repository
.
get
(
url
)
fun
get
All
(
url
:
String
)
=
repository
.
get
(
url
)
/**
/**
* Get a list of chat rooms that contains the name parameter.
* Get a list of chat rooms that contains the name parameter.
...
@@ -23,7 +23,7 @@ class GetChatRoomsInteractor @Inject constructor(private val repository: ChatRoo
...
@@ -23,7 +23,7 @@ class GetChatRoomsInteractor @Inject constructor(private val repository: ChatRoo
* @param name The name of chat room to look for or a chat room that contains this name.
* @param name The name of chat room to look for or a chat room that contains this name.
* @return A list of ChatRoom objects with the given name.
* @return A list of ChatRoom objects with the given name.
*/
*/
suspend
fun
getByName
(
url
:
String
,
name
:
String
):
List
<
ChatRoom
>
=
withContext
(
CommonPool
)
{
suspend
fun
get
All
ByName
(
url
:
String
,
name
:
String
):
List
<
ChatRoom
>
=
withContext
(
CommonPool
)
{
val
allChatRooms
=
repository
.
get
(
url
)
val
allChatRooms
=
repository
.
get
(
url
)
if
(
name
.
isEmpty
())
{
if
(
name
.
isEmpty
())
{
return
@withContext
allChatRooms
return
@withContext
allChatRooms
...
@@ -34,11 +34,11 @@ class GetChatRoomsInteractor @Inject constructor(private val repository: ChatRoo
...
@@ -34,11 +34,11 @@ class GetChatRoomsInteractor @Inject constructor(private val repository: ChatRoo
}
}
/**
/**
* Get a specific
room
by its id.
* Get a specific
[ChatRoom]
by its id.
*
*
* @param serverUrl The server url where the room is.
* @param serverUrl The server url where the room is.
* @param roomId The id of the room to get.
* @param roomId The id of the room to get.
* @return The
ChatRoom
object or null if we couldn't find any.
* @return The
[ChatRoom]
object or null if we couldn't find any.
*/
*/
suspend
fun
getById
(
serverUrl
:
String
,
roomId
:
String
):
ChatRoom
?
=
withContext
(
CommonPool
)
{
suspend
fun
getById
(
serverUrl
:
String
,
roomId
:
String
):
ChatRoom
?
=
withContext
(
CommonPool
)
{
val
allChatRooms
=
repository
.
get
(
serverUrl
)
val
allChatRooms
=
repository
.
get
(
serverUrl
)
...
@@ -46,4 +46,43 @@ class GetChatRoomsInteractor @Inject constructor(private val repository: ChatRoo
...
@@ -46,4 +46,43 @@ class GetChatRoomsInteractor @Inject constructor(private val repository: ChatRoo
it
.
id
==
roomId
it
.
id
==
roomId
}
}
}
}
/**
* Get a specific [ChatRoom] by its name.
*
* @param serverUrl The server url where the room is.
* @param name The name of the room to get.
* @return The [ChatRoom] object or null if we couldn't find any.
*/
fun
getByName
(
serverUrl
:
String
,
name
:
String
):
ChatRoom
?
{
return
getAll
(
serverUrl
).
toMutableList
().
find
{
chatRoom
->
chatRoom
.
name
==
name
}
}
/**
* Add a [ChatRoom].
*
* @param url The server url.
* @param chatRoom The [ChatRoom] to be added to the list.
*/
fun
add
(
url
:
String
,
chatRoom
:
ChatRoom
)
{
val
chatRooms
:
MutableList
<
ChatRoom
>
=
getAll
(
url
).
toMutableList
()
synchronized
(
this
)
{
chatRooms
.
add
(
chatRoom
)
}
repository
.
save
(
url
,
chatRooms
)
}
/**
* Removes a [ChatRoom].
*
* @param url The server url.
* @param chatRoom The [ChatRoom] to be removed from the list.
*/
fun
remove
(
url
:
String
,
chatRoom
:
ChatRoom
)
{
val
chatRooms
:
MutableList
<
ChatRoom
>
=
getAll
(
url
).
toMutableList
()
synchronized
(
this
)
{
chatRooms
.
removeAll
{
chatRoom_
->
chatRoom_
.
id
==
chatRoom
.
id
}
}
repository
.
save
(
url
,
chatRooms
)
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/SaveActiveUsersInteractor.kt
0 → 100644
View file @
73d09b24
package
chat.rocket.android.server.domain
import
chat.rocket.common.model.User
import
javax.inject.Inject
class
SaveActiveUsersInteractor
@Inject
constructor
(
private
val
repository
:
ActiveUsersRepository
,
private
val
getActiveUsersInteractor
:
GetActiveUsersInteractor
)
{
fun
save
(
url
:
String
,
activeUsers
:
List
<
User
>)
{
repository
.
save
(
url
,
activeUsers
)
}
fun
addActiveUser
(
url
:
String
,
user
:
User
)
{
val
activeUserList
:
MutableList
<
User
>
=
getActiveUsersInteractor
.
getAllActiveUsers
(
url
).
toMutableList
()
synchronized
(
this
)
{
activeUserList
.
add
(
user
)
}
save
(
url
,
activeUserList
)
}
fun
updateActiveUser
(
url
:
String
,
user
:
User
)
{
getActiveUsersInteractor
.
getActiveUserById
(
url
,
user
.
id
)
?.
let
{
val
newUser
=
User
(
id
=
user
.
id
,
name
=
user
.
name
?:
it
.
name
,
username
=
user
.
username
?:
it
.
username
,
status
=
user
.
status
?:
it
.
status
,
emails
=
user
.
emails
?:
it
.
emails
,
utcOffset
=
user
.
utcOffset
?:
it
.
utcOffset
)
val
activeUserList
:
MutableList
<
User
>
=
getActiveUsersInteractor
.
getAllActiveUsers
(
url
).
toMutableList
()
synchronized
(
this
)
{
activeUserList
.
removeAll
{
user_
->
user_
.
id
==
user
.
id
}
}
activeUserList
.
add
(
newUser
)
save
(
url
,
activeUserList
)
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/infraestructure/ConnectionManager.kt
View file @
73d09b24
package
chat.rocket.android.server.infraestructure
package
chat.rocket.android.server.infraestructure
import
chat.rocket.common.model.BaseRoom
import
chat.rocket.common.model.BaseRoom
import
chat.rocket.common.model.User
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.realtime.subscribeSubscriptions
import
chat.rocket.core.internal.realtime.subscribeSubscriptions
import
chat.rocket.core.internal.realtime.subscribeRooms
import
chat.rocket.core.internal.realtime.subscribeRooms
import
chat.rocket.core.internal.realtime.subscribeUserData
import
chat.rocket.core.internal.realtime.subscribeUserData
import
chat.rocket.core.internal.realtime.subscribeActiveUsers
import
chat.rocket.core.internal.realtime.subscribeRoomMessages
import
chat.rocket.core.internal.realtime.subscribeRoomMessages
import
chat.rocket.core.internal.realtime.unsubscribe
import
chat.rocket.core.internal.realtime.unsubscribe
import
chat.rocket.core.internal.realtime.socket.connect
import
chat.rocket.core.internal.realtime.socket.connect
...
@@ -28,11 +30,13 @@ class ConnectionManager(internal val client: RocketChatClient) {
...
@@ -28,11 +30,13 @@ class ConnectionManager(internal val client: RocketChatClient) {
private
val
roomAndSubscriptionChannels
=
ArrayList
<
Channel
<
StreamMessage
<
BaseRoom
>>>()
private
val
roomAndSubscriptionChannels
=
ArrayList
<
Channel
<
StreamMessage
<
BaseRoom
>>>()
private
val
roomMessagesChannels
=
LinkedHashMap
<
String
,
Channel
<
Message
>>()
private
val
roomMessagesChannels
=
LinkedHashMap
<
String
,
Channel
<
Message
>>()
private
val
userDataChannels
=
ArrayList
<
Channel
<
Myself
>>()
private
val
userDataChannels
=
ArrayList
<
Channel
<
Myself
>>()
private
val
activeUsersChannels
=
ArrayList
<
Channel
<
User
>>()
private
val
subscriptionIdMap
=
HashMap
<
String
,
String
>()
private
val
subscriptionIdMap
=
HashMap
<
String
,
String
>()
private
var
subscriptionId
:
String
?
=
null
private
var
subscriptionId
:
String
?
=
null
private
var
roomsId
:
String
?
=
null
private
var
roomsId
:
String
?
=
null
private
var
userId
:
String
?
=
null
private
var
userDataId
:
String
?
=
null
private
var
activeUserId
:
String
?
=
null
fun
connect
()
{
fun
connect
()
{
if
(
connectJob
?.
isActive
==
true
&&
(
state
!
is
State
.
Disconnected
))
{
if
(
connectJob
?.
isActive
==
true
&&
(
state
!
is
State
.
Disconnected
))
{
...
@@ -61,8 +65,12 @@ class ConnectionManager(internal val client: RocketChatClient) {
...
@@ -61,8 +65,12 @@ class ConnectionManager(internal val client: RocketChatClient) {
roomsId
=
id
roomsId
=
id
}
}
client
.
subscribeUserData
{
_
,
id
->
client
.
subscribeUserData
{
_
,
id
->
Timber
.
d
(
"Subscribed to the user: $id"
)
Timber
.
d
(
"Subscribed to the userData id: $id"
)
userId
=
id
userDataId
=
id
}
client
.
subscribeActiveUsers
{
_
,
id
->
Timber
.
d
(
"Subscribed to the activeUser id: $id"
)
activeUserId
=
id
}
}
resubscribeRooms
()
resubscribeRooms
()
...
@@ -115,6 +123,14 @@ class ConnectionManager(internal val client: RocketChatClient) {
...
@@ -115,6 +123,14 @@ class ConnectionManager(internal val client: RocketChatClient) {
}
}
}
}
launch
(
parent
=
connectJob
)
{
for
(
user
in
client
.
activeUsersChannel
)
{
Timber
.
d
(
"Got activeUsers"
)
for
(
channel
in
activeUsersChannels
)
{
channel
.
send
(
user
)
}
}
}
client
.
connect
()
client
.
connect
()
// Broadcast initial state...
// Broadcast initial state...
...
@@ -154,6 +170,10 @@ class ConnectionManager(internal val client: RocketChatClient) {
...
@@ -154,6 +170,10 @@ class ConnectionManager(internal val client: RocketChatClient) {
fun
removeUserDataChannel
(
channel
:
Channel
<
Myself
>)
=
userDataChannels
.
remove
(
channel
)
fun
removeUserDataChannel
(
channel
:
Channel
<
Myself
>)
=
userDataChannels
.
remove
(
channel
)
fun
addActiveUserChannel
(
channel
:
Channel
<
User
>)
=
activeUsersChannels
.
add
(
channel
)
fun
removeActiveUserChannel
(
channel
:
Channel
<
User
>)
=
activeUsersChannels
.
remove
(
channel
)
fun
subscribeRoomMessages
(
roomId
:
String
,
channel
:
Channel
<
Message
>)
{
fun
subscribeRoomMessages
(
roomId
:
String
,
channel
:
Channel
<
Message
>)
{
val
oldSub
=
roomMessagesChannels
.
put
(
roomId
,
channel
)
val
oldSub
=
roomMessagesChannels
.
put
(
roomId
,
channel
)
if
(
oldSub
!=
null
)
{
if
(
oldSub
!=
null
)
{
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/MemoryActiveUsersRepository.kt
0 → 100644
View file @
73d09b24
package
chat.rocket.android.server.infraestructure
import
chat.rocket.android.server.domain.ActiveUsersRepository
import
chat.rocket.common.model.User
class
MemoryActiveUsersRepository
:
ActiveUsersRepository
{
val
cache
=
HashMap
<
String
,
List
<
User
>>()
override
fun
save
(
url
:
String
,
activeUsers
:
List
<
User
>)
{
cache
[
url
]
=
activeUsers
}
override
fun
get
(
url
:
String
):
List
<
User
>
=
cache
[
url
]
?:
emptyList
()
}
\ No newline at end of file
app/src/main/res/drawable/ic_hashtag_12dp.xml
0 → 100644
View file @
73d09b24
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"12dp"
android:height=
"12dp"
android:viewportHeight=
"12"
android:viewportWidth=
"12"
>
<path
android:fillColor=
"#9EA2A8"
android:fillType=
"evenOdd"
android:pathData=
"M2.4,0h1.2v12h-1.2z"
android:strokeColor=
"#00000000"
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#9EA2A8"
android:fillType=
"evenOdd"
android:pathData=
"M0,2.4h12v1.2h-12z"
android:strokeColor=
"#00000000"
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#9EA2A8"
android:fillType=
"evenOdd"
android:pathData=
"M0,8.4h12v1.2h-12z"
android:strokeColor=
"#00000000"
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#9EA2A8"
android:fillType=
"evenOdd"
android:pathData=
"M8.4,0h1.2v12h-1.2z"
android:strokeColor=
"#00000000"
android:strokeWidth=
"1"
/>
</vector>
\ No newline at end of file
app/src/main/res/drawable/ic_lock_12_dp.xml
0 → 100644
View file @
73d09b24
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"12dp"
android:height=
"12dp"
android:viewportWidth=
"12"
android:viewportHeight=
"12"
>
<path
android:pathData=
"M1.5,5.5h9v6h-9z"
android:strokeWidth=
"1"
android:fillColor=
"#00000000"
android:strokeColor=
"#9EA2A8"
android:fillType=
"evenOdd"
/>
<path
android:pathData=
"M2.5,5.5L9.5,5.5L9.5,4C9.5,2.067 7.933,0.5 6,0.5C4.067,0.5 2.5,2.067 2.5,4L2.5,5.5Z"
android:strokeWidth=
"1"
android:fillColor=
"#00000000"
android:strokeColor=
"#9EA2A8"
android:fillType=
"evenOdd"
/>
</vector>
app/src/main/res/drawable/ic_status_away_
24
dp.xml
→
app/src/main/res/drawable/ic_status_away_
12
dp.xml
View file @
73d09b24
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"
24
dp"
android:width=
"
12
dp"
android:height=
"
24
dp"
android:height=
"
12
dp"
android:viewportHeight=
"
24
"
android:viewportHeight=
"
12
"
android:viewportWidth=
"
24
"
>
android:viewportWidth=
"
12
"
>
<path
<path
android:fillColor=
"#FFFFD100"
android:fillColor=
"#FFFFD100"
android:fillType=
"evenOdd"
android:fillType=
"evenOdd"
android:pathData=
"M
12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-2
0 0"
android:pathData=
"M
6,6m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-1
0 0"
android:strokeColor=
"#00000000"
android:strokeColor=
"#00000000"
android:strokeWidth=
"1"
/>
android:strokeWidth=
"1"
/>
<path
</vector>
android:fillColor=
"#00000000"
\ No newline at end of file
android:fillType=
"evenOdd"
android:pathData=
"M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
android:strokeColor=
"#FFFFFFFF"
android:strokeWidth=
"2"
/>
</vector>
app/src/main/res/drawable/ic_status_busy_
24
dp.xml
→
app/src/main/res/drawable/ic_status_busy_
12
dp.xml
View file @
73d09b24
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"
24
dp"
android:width=
"
12
dp"
android:height=
"
24
dp"
android:height=
"
12
dp"
android:viewportHeight=
"
24
"
android:viewportHeight=
"
12
"
android:viewportWidth=
"
24
"
>
android:viewportWidth=
"
12
"
>
<path
<path
android:fillColor=
"#FFFF2A57"
android:fillColor=
"#FFFF2A57"
android:fillType=
"evenOdd"
android:fillType=
"evenOdd"
android:pathData=
"M
12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-2
0 0"
android:pathData=
"M
6,6m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-1
0 0"
android:strokeColor=
"#00000000"
android:strokeColor=
"#00000000"
android:strokeWidth=
"1"
/>
android:strokeWidth=
"1"
/>
<path
</vector>
android:fillColor=
"#00000000"
\ No newline at end of file
android:fillType=
"evenOdd"
android:pathData=
"M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
android:strokeColor=
"#FFFFFFFF"
android:strokeWidth=
"2"
/>
</vector>
app/src/main/res/drawable/ic_status_invisible_
24
dp.xml
→
app/src/main/res/drawable/ic_status_invisible_
12
dp.xml
View file @
73d09b24
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"
24
dp"
android:width=
"
12
dp"
android:height=
"
24
dp"
android:height=
"
12
dp"
android:viewportHeight=
"
24
"
android:viewportHeight=
"
12
"
android:viewportWidth=
"
24
"
>
android:viewportWidth=
"
12
"
>
<path
<path
android:fillColor=
"#FFCBCED1"
android:fillColor=
"#FFCBCED1"
android:fillType=
"evenOdd"
android:fillType=
"evenOdd"
android:pathData=
"M
12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-2
0 0"
android:pathData=
"M
6,6m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-1
0 0"
android:strokeColor=
"#00000000"
android:strokeColor=
"#00000000"
android:strokeWidth=
"1"
/>
android:strokeWidth=
"1"
/>
<path
</vector>
android:fillColor=
"#00000000"
\ No newline at end of file
android:fillType=
"evenOdd"
android:pathData=
"M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
android:strokeColor=
"#FFFFFFFF"
android:strokeWidth=
"2"
/>
</vector>
app/src/main/res/drawable/ic_status_online_
24
dp.xml
→
app/src/main/res/drawable/ic_status_online_
12
dp.xml
View file @
73d09b24
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"
24
dp"
android:width=
"
12
dp"
android:height=
"
24
dp"
android:height=
"
12
dp"
android:viewportHeight=
"
24
"
android:viewportHeight=
"
12
"
android:viewportWidth=
"
24
"
>
android:viewportWidth=
"
12
"
>
<path
<path
android:fillColor=
"#FF2DE0A5"
android:fillColor=
"#FF2DE0A5"
android:fillType=
"evenOdd"
android:fillType=
"evenOdd"
android:pathData=
"M
12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-2
0 0"
android:pathData=
"M
6,6m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-1
0 0"
android:strokeColor=
"#00000000"
android:strokeColor=
"#00000000"
android:strokeWidth=
"1"
/>
android:strokeWidth=
"1"
/>
<path
</vector>
android:fillColor=
"#00000000"
\ No newline at end of file
android:fillType=
"evenOdd"
android:pathData=
"M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
android:strokeColor=
"#FFFFFFFF"
android:strokeWidth=
"2"
/>
</vector>
app/src/main/res/drawable/user_status_white.xml
deleted
100644 → 0
View file @
3e457b9d
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"10dp"
android:height=
"10dp"
android:viewportWidth=
"10.0"
android:viewportHeight=
"10.0"
>
<path
android:pathData=
"M5,5m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-10 0"
android:fillType=
"evenOdd"
android:fillColor=
"#FFFFFF"
android:strokeWidth=
"1"
/>
</vector>
\ No newline at end of file
app/src/main/res/layout/fragment_chat_rooms.xml
View file @
73d09b24
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_centerInParent=
"true"
android:layout_centerInParent=
"true"
android:visibility=
"gone"
app:indicatorColor=
"@color/black"
app:indicatorColor=
"@color/black"
app:indicatorName=
"BallPulseIndicator"
/>
app:indicatorName=
"BallPulseIndicator"
/>
...
@@ -33,15 +34,15 @@
...
@@ -33,15 +34,15 @@
android:id=
"@+id/connection_status_text"
android:id=
"@+id/connection_status_text"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"32dp"
android:layout_height=
"32dp"
android:alpha=
"0"
android:background=
"@color/colorPrimary"
android:background=
"@color/colorPrimary"
android:elevation=
"4dp"
android:elevation=
"4dp"
android:textColor=
"@color/white"
android:gravity=
"center"
android:gravity=
"center"
android:textAppearance=
"@style/TextAppearance.AppCompat.Body2"
android:textAppearance=
"@style/TextAppearance.AppCompat.Body2"
android:textColor=
"@color/white"
android:visibility=
"gone"
android:visibility=
"gone"
android:alpha=
"0"
tools:alpha=
"1"
tools:alpha=
"1"
tools:
visibility=
"visible
"
tools:
text=
"connected
"
tools:
text=
"connected"
/>
tools:
visibility=
"visible"
/>
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/layout/item_change_status.xml
View file @
73d09b24
...
@@ -15,7 +15,7 @@
...
@@ -15,7 +15,7 @@
android:paddingStart=
"16dp"
android:paddingStart=
"16dp"
android:paddingTop=
"8dp"
android:paddingTop=
"8dp"
android:drawablePadding=
"10dp"
android:drawablePadding=
"10dp"
android:drawableStart=
"@drawable/ic_status_online_
24
dp"
android:drawableStart=
"@drawable/ic_status_online_
12
dp"
android:text=
"@string/action_online"
android:text=
"@string/action_online"
android:background=
"?selectableItemBackground"
/>
android:background=
"?selectableItemBackground"
/>
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
android:paddingStart=
"16dp"
android:paddingStart=
"16dp"
android:paddingTop=
"8dp"
android:paddingTop=
"8dp"
android:drawablePadding=
"10dp"
android:drawablePadding=
"10dp"
android:drawableStart=
"@drawable/ic_status_away_
24
dp"
android:drawableStart=
"@drawable/ic_status_away_
12
dp"
android:text=
"@string/action_away"
android:text=
"@string/action_away"
android:background=
"?selectableItemBackground"
/>
android:background=
"?selectableItemBackground"
/>
...
@@ -41,7 +41,7 @@
...
@@ -41,7 +41,7 @@
android:paddingStart=
"16dp"
android:paddingStart=
"16dp"
android:paddingTop=
"8dp"
android:paddingTop=
"8dp"
android:drawablePadding=
"10dp"
android:drawablePadding=
"10dp"
android:drawableStart=
"@drawable/ic_status_busy_
24
dp"
android:drawableStart=
"@drawable/ic_status_busy_
12
dp"
android:text=
"@string/action_busy"
android:text=
"@string/action_busy"
android:background=
"?selectableItemBackground"
/>
android:background=
"?selectableItemBackground"
/>
...
@@ -54,7 +54,7 @@
...
@@ -54,7 +54,7 @@
android:paddingStart=
"16dp"
android:paddingStart=
"16dp"
android:paddingTop=
"8dp"
android:paddingTop=
"8dp"
android:drawablePadding=
"10dp"
android:drawablePadding=
"10dp"
android:drawableStart=
"@drawable/ic_status_invisible_
24
dp"
android:drawableStart=
"@drawable/ic_status_invisible_
12
dp"
android:text=
"@string/action_invisible"
android:text=
"@string/action_invisible"
android:background=
"?selectableItemBackground"
/>
android:background=
"?selectableItemBackground"
/>
...
...
app/src/main/res/layout/item_chat.xml
View file @
73d09b24
...
@@ -5,62 +5,70 @@
...
@@ -5,62 +5,70 @@
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:background=
"?android:attr/selectableItemBackground"
android:background=
"?android:attr/selectableItemBackground"
android:padding
Start=
"@dimen/screen_edge_left_and_right
_padding"
android:padding
Bottom=
"@dimen/chat_item_top_and_bottom
_padding"
android:paddingEnd=
"@dimen/screen_edge_left_and_right_padding"
android:paddingEnd=
"@dimen/screen_edge_left_and_right_padding"
android:padding
Top=
"@dimen/chat_item_top_and_bottom
_padding"
android:padding
Start=
"@dimen/screen_edge_left_and_right
_padding"
android:padding
Bottom
=
"@dimen/chat_item_top_and_bottom_padding"
>
android:padding
Top
=
"@dimen/chat_item_top_and_bottom_padding"
>
<com.facebook.drawee.view.SimpleDraweeView
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_avatar"
android:id=
"@+id/image_avatar"
android:layout_width=
"40dp"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
android:layout_height=
"40dp"
app:roundedCornerRadius=
"3dp"
android:layout_marginTop=
"5dp"
android:layout_marginTop=
"6dp"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
/>
app:layout_constraintTop_toTopOf=
"parent"
app:roundedCornerRadius=
"3dp"
/>
<ImageView
android:id=
"@+id/image_chat_icon"
android:layout_width=
"12dp"
android:layout_height=
"12dp"
android:layout_marginStart=
"16dp"
app:layout_constraintStart_toEndOf=
"@+id/image_avatar"
app:layout_constraintTop_toTopOf=
"@+id/image_avatar"
tools:src=
"@drawable/ic_hashtag_12dp"
/>
<TextView
<TextView
android:id=
"@+id/text_chat_name"
android:id=
"@+id/text_chat_name"
style=
"@style/ChatRoom.Name.TextView"
style=
"@style/ChatRoom.Name.TextView"
android:layout_width=
"
0dp
"
android:layout_width=
"
wrap_content
"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"16dp"
android:layout_marginStart=
"8dp"
app:layout_constraintStart_toEndOf=
"@id/image_avatar"
android:textDirection=
"locale"
android:textDirection=
"locale"
tools:text=
"General"
/>
app:layout_constraintStart_toEndOf=
"@+id/image_chat_icon"
tools:text=
"general"
/>
<TextView
<TextView
android:id=
"@+id/text_last_message_date_time"
android:id=
"@+id/text_last_message_date_time"
style=
"@style/Timestamp.TextView"
style=
"@style/Timestamp.TextView"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"5dp"
android:layout_marginStart=
"8dp"
android:layout_marginEnd=
"5dp"
app:layout_constraintBottom_toBottomOf=
"@+id/text_chat_name"
app:layout_constraintBaseline_toBaselineOf=
"@+id/text_chat_name"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toTopOf=
"@+id/text_chat_name"
tools:text=
"11:45 AM"
/>
tools:text=
"11:45 AM"
/>
<TextView
<TextView
android:id=
"@+id/text_last_message"
android:id=
"@+id/text_last_message"
android:layout_width=
"0dp"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginEnd=
"8dp"
android:layout_marginTop=
"2dp"
android:ellipsize=
"end"
android:ellipsize=
"end"
android:maxLines=
"2"
android:maxLines=
"2"
android:layout_marginTop=
"2dp"
app:layout_constraintStart_toStartOf=
"@id/text_chat_name"
app:layout_constraintTop_toBottomOf=
"@id/text_chat_name"
app:layout_constraintEnd_toStartOf=
"@id/layout_unread_messages_badge"
android:textDirection=
"locale"
android:textDirection=
"locale"
tools:text=
"You: Type something that is very big and need at least to lines, or maybe even more"
/>
app:layout_constraintEnd_toStartOf=
"@+id/layout_unread_messages_badge"
app:layout_constraintStart_toStartOf=
"@+id/image_chat_icon"
app:layout_constraintTop_toBottomOf=
"@+id/text_chat_name"
tools:text=
"Filipe de Lima Brito: Type something that is very big and need at least to lines, or maybe even more"
/>
<include
<include
android:id=
"@+id/layout_unread_messages_badge"
android:id=
"@+id/layout_unread_messages_badge"
layout=
"@layout/unread_messages_badge"
layout=
"@layout/unread_messages_badge"
android:layout_width=
"18dp"
android:layout_width=
"18dp"
android:layout_height=
"18dp"
android:layout_height=
"18dp"
android:layout_marginStart=
"5dp"
app:layout_constraintEnd_toEndOf=
"parent"
android:layout_marginEnd=
"5dp"
app:layout_constraintTop_toTopOf=
"@+id/text_last_message"
/>
app:layout_constraintTop_toTopOf=
"@id/text_last_message"
app:layout_constraintEnd_toEndOf=
"parent"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/nav_header.xml
View file @
73d09b24
...
@@ -43,8 +43,8 @@
...
@@ -43,8 +43,8 @@
<ImageView
<ImageView
android:id=
"@+id/image_user_status"
android:id=
"@+id/image_user_status"
android:layout_width=
"1
4
dp"
android:layout_width=
"1
2
dp"
android:layout_height=
"1
4
dp"
android:layout_height=
"1
2
dp"
app:layout_constraintStart_toStartOf=
"parent"
/>
app:layout_constraintStart_toStartOf=
"parent"
/>
<TextView
<TextView
...
...
app/src/main/res/layout/suggestion_member_item.xml
View file @
73d09b24
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<
Relative
Layout
xmlns:android=
"http://schemas.android.com/apk/res/android"
<
android.support.constraint.Constraint
Layout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"2dp"
android:layout_marginBottom=
"2dp"
android:layout_marginEnd=
"2dp"
android:layout_marginEnd=
"2dp"
android:layout_marginLeft=
"8dp"
android:layout_marginRight=
"2dp"
android:layout_marginStart=
"8dp"
android:layout_marginStart=
"8dp"
android:layout_marginTop=
"2dp"
android:layout_marginTop=
"2dp"
android:background=
"@color/suggestion_background_color"
>
android:background=
"@color/suggestion_background_color"
>
<FrameLayout
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_avatar_container"
android:id=
"@+id/image_avatar"
android:layout_width=
"24dp"
android:layout_height=
"24dp"
app:roundedCornerRadius=
"3dp"
tools:src=
"@tools:sample/avatars"
/>
<ImageView
android:id=
"@+id/image_status"
android:layout_width=
"12dp"
android:layout_height=
"12dp"
android:layout_marginStart=
"5dp"
app:layout_constraintBottom_toBottomOf=
"@+id/image_avatar"
app:layout_constraintStart_toEndOf=
"@+id/image_avatar"
app:layout_constraintTop_toTopOf=
"@+id/image_avatar"
/>
<TextView
android:id=
"@+id/text_username"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_centerVertical=
"true"
>
android:layout_marginStart=
"5dp"
android:maxLines=
"1"
<com.facebook.drawee.view.SimpleDraweeView
android:textColor=
"@color/black"
android:id=
"@+id/image_avatar"
android:textSize=
"16sp"
android:layout_width=
"24dp"
app:layout_constraintBottom_toBottomOf=
"parent"
android:layout_height=
"24dp"
app:layout_constraintStart_toEndOf=
"@+id/image_status"
android:layout_marginTop=
"4dp"
app:layout_constraintTop_toTopOf=
"parent"
android:layout_marginBottom=
"4dp"
tools:text=
"@tools:sample/full_names"
/>
app:roundedCornerRadius=
"3dp"
tools:src=
"@tools:sample/avatars"
/>
<TextView
android:id=
"@+id/text_name"
<ImageView
android:layout_width=
"wrap_content"
android:id=
"@+id/image_status"
android:layout_width=
"12dp"
android:layout_height=
"12dp"
android:layout_gravity=
"bottom|end"
android:background=
"@drawable/user_status_white"
android:padding=
"2dp"
/>
</FrameLayout>
<RelativeLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_centerVertical=
"true"
android:layout_marginStart=
"5dp"
android:layout_toEndOf=
"@id/image_avatar_container"
android:ellipsize=
"end"
android:layout_toRightOf=
"@id/image_avatar_container"
android:maxLines=
"1"
android:background=
"@color/suggestion_background_color"
>
android:textColor=
"@color/gray_material"
android:textSize=
"16sp"
<TextView
app:layout_constraintBottom_toBottomOf=
"parent"
android:id=
"@+id/text_username"
app:layout_constraintStart_toEndOf=
"@+id/text_username"
android:layout_width=
"wrap_content"
app:layout_constraintTop_toTopOf=
"parent"
android:layout_height=
"wrap_content"
tools:text=
"@tools:sample/full_names"
/>
android:layout_centerVertical=
"true"
android:maxLines=
"1"
</android.support.constraint.ConstraintLayout>
android:textColor=
"@color/black"
\ No newline at end of file
android:textSize=
"16sp"
tools:text=
"@tools:sample/full_names"
/>
<TextView
android:id=
"@+id/text_name"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_alignParentEnd=
"true"
android:layout_alignParentRight=
"true"
android:layout_centerVertical=
"true"
android:layout_toEndOf=
"@+id/text_username"
android:layout_toRightOf=
"@+id/text_username"
android:maxLines=
"1"
android:paddingLeft=
"8dp"
android:paddingStart=
"8dp"
android:textColor=
"@color/gray_material"
android:textSize=
"16sp"
tools:text=
"@tools:sample/full_names"
/>
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/layout/suggestion_room_item.xml
View file @
73d09b24
...
@@ -3,43 +3,30 @@
...
@@ -3,43 +3,30 @@
xmlns:tools=
"http://schemas.android.com/tools"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_margin=
"2dp"
android:layout_marginBottom=
"2dp"
android:layout_marginEnd=
"2dp"
android:layout_marginStart=
"8dp"
android:layout_marginTop=
"2dp"
android:background=
"@color/suggestion_background_color"
>
android:background=
"@color/suggestion_background_color"
>
<RelativeLayout
<TextView
android:layout_width=
"match_parent"
android:id=
"@+id/text_name"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:
layout_centerVertical=
"true
"
android:
maxLines=
"1
"
android:
layout_toEndOf=
"@id/image_avatar_container
"
android:
textColor=
"@color/black
"
android:
layout_toRightOf=
"@id/image_avatar_container
"
android:
textSize=
"16sp
"
android:background=
"@color/suggestion_background_color"
>
tools:text=
"@tools:sample/full_names"
/
>
<TextView
<TextView
android:id=
"@+id/text_name"
android:id=
"@+id/text_fullname"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_centerVertical=
"true"
android:layout_toEndOf=
"@+id/text_name"
android:maxLines=
"1"
android:maxLines=
"1"
android:textColor=
"@color/black"
android:layout_marginStart=
"8dp"
android:textSize=
"16sp"
android:textColor=
"@color/gray_material"
tools:text=
"@tools:sample/full_names"
/>
android:textSize=
"16sp"
tools:text=
"@tools:sample/full_names"
/>
<TextView
android:id=
"@+id/text_fullname"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_alignParentEnd=
"true"
android:layout_alignParentRight=
"true"
android:layout_centerVertical=
"true"
android:layout_toEndOf=
"@+id/text_name"
android:layout_toRightOf=
"@+id/text_name"
android:maxLines=
"1"
android:paddingLeft=
"8dp"
android:paddingStart=
"8dp"
android:textColor=
"@color/gray_material"
android:textSize=
"16sp"
tools:text=
"@tools:sample/full_names"
/>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/values-hi-rIN/strings.xml
View file @
73d09b24
<resources
<resources>
xmlns:tools=
"http://schemas.android.com/tools"
tools:ignore=
"MissingTranslation"
>
<!-- Titles -->
<!-- Titles -->
<string
name=
"title_sign_in_your_server"
>
अपने सर्वर में साइन इन करें
</string>
<string
name=
"title_sign_in_your_server"
>
अपने सर्वर में साइन इन करें
</string>
<string
name=
"title_log_in"
>
लॉग इन करें
</string>
<string
name=
"title_log_in"
>
लॉग इन करें
</string>
...
@@ -82,6 +79,8 @@
...
@@ -82,6 +79,8 @@
<string
name=
"msg_preview_photo"
>
तस्वीरें
</string>
<string
name=
"msg_preview_photo"
>
तस्वीरें
</string>
<string
name=
"msg_unread_messages"
>
अपठित संदेश
</string>
<string
name=
"msg_unread_messages"
>
अपठित संदेश
</string>
<string
name=
"msg_no_messages_yet"
>
अभी तक कोई पोस्ट नहीं
</string>
<string
name=
"msg_no_messages_yet"
>
अभी तक कोई पोस्ट नहीं
</string>
<string
name=
"msg_version"
>
वर्शन
</string>
<string
name=
"msg_build"
>
बिल्ड
</string>
<string
name=
"msg_ok"
>
OK
</string>
<string
name=
"msg_ok"
>
OK
</string>
<string
name=
"msg_ver_not_recommended"
>
<string
name=
"msg_ver_not_recommended"
>
ऐसा लगता है कि आपका सर्वर संस्करण अनुशंसित संस्करण %1$s के नीचे है।\nआप अभी भी लॉगिन कर सकते हैं लेकिन आप अप्रत्याशित व्यवहार का अनुभव कर सकते हैं
ऐसा लगता है कि आपका सर्वर संस्करण अनुशंसित संस्करण %1$s के नीचे है।\nआप अभी भी लॉगिन कर सकते हैं लेकिन आप अप्रत्याशित व्यवहार का अनुभव कर सकते हैं
...
@@ -89,8 +88,12 @@
...
@@ -89,8 +88,12 @@
<string
name=
"msg_ver_not_minimum"
>
<string
name=
"msg_ver_not_minimum"
>
ऐसा लगता है कि आपका सर्वर संस्करण न्यूनतम आवश्यक संस्करण %1$s से कम है।\nकृपया लॉगिन करने के लिए अपने सर्वर को अपग्रेड करें!
ऐसा लगता है कि आपका सर्वर संस्करण न्यूनतम आवश्यक संस्करण %1$s से कम है।\nकृपया लॉगिन करने के लिए अपने सर्वर को अपग्रेड करें!
</string>
</string>
<string
name=
"msg_version"
>
वर्शन
</string>
<string
name=
"msg_proceed"
>
आगे बढ़ें
</string>
<string
name=
"msg_build"
>
बिल्ड
</string>
<string
name=
"msg_cancel"
>
रद्द करना
</string>
<string
name=
"msg_warning"
>
चेतावनी
</string>
<string
name=
"msg_http_insecure"
>
HTTP का उपयोग करते समय, आप एक असुरक्षित सर्वर से कनेक्ट हो रहे हैं। हम आपको ऐसा करने की सलाह नहीं देते हैं।
</string>
<string
name=
"msg_error_checking_server_version"
>
आपके सर्वर संस्करण की जांच करते समय एक त्रुटि आई है, कृपया पुनः प्रयास करें
</string>
<string
name=
"msg_invalid_server_protocol"
>
चयनित प्रोटोकॉल इस सर्वर द्वारा स्वीकार नहीं किया गया है, HTTPS का उपयोग करने का प्रयास करें
</string>
<!-- System messages -->
<!-- System messages -->
<string
name=
"message_room_name_changed"
>
%2$s ने रूम का नाम बदलकर %1$s किया
</string>
<string
name=
"message_room_name_changed"
>
%2$s ने रूम का नाम बदलकर %1$s किया
</string>
...
@@ -189,4 +192,4 @@
...
@@ -189,4 +192,4 @@
<string
name=
"notif_action_reply_hint"
>
जवाब
</string>
<string
name=
"notif_action_reply_hint"
>
जवाब
</string>
<string
name=
"notif_error_sending"
>
उत्तर विफल हुआ है। कृपया फिर से प्रयास करें।
</string>
<string
name=
"notif_error_sending"
>
उत्तर विफल हुआ है। कृपया फिर से प्रयास करें।
</string>
<string
name=
"notif_success_sending"
>
संदेश भेजा गया %1$s!
</string>
<string
name=
"notif_success_sending"
>
संदेश भेजा गया %1$s!
</string>
</resources>
</resources>
\ No newline at end of file
app/src/main/res/values/dimens.xml
View file @
73d09b24
...
@@ -5,7 +5,6 @@
...
@@ -5,7 +5,6 @@
<dimen
name=
"screen_edge_left_and_right_margins"
>
16dp
</dimen>
<dimen
name=
"screen_edge_left_and_right_margins"
>
16dp
</dimen>
<dimen
name=
"screen_edge_left_and_right_padding"
>
16dp
</dimen>
<dimen
name=
"screen_edge_left_and_right_padding"
>
16dp
</dimen>
<dimen
name=
"chat_item_top_and_bottom_padding"
>
12dp
</dimen>
<dimen
name=
"message_item_top_and_bottom_padding"
>
6dp
</dimen>
<dimen
name=
"message_item_top_and_bottom_padding"
>
6dp
</dimen>
<dimen
name=
"member_item_top_and_bottom_padding"
>
6dp
</dimen>
<dimen
name=
"member_item_top_and_bottom_padding"
>
6dp
</dimen>
...
@@ -23,6 +22,10 @@
...
@@ -23,6 +22,10 @@
<dimen
name=
"nav_header_height"
>
140dp
</dimen>
<dimen
name=
"nav_header_height"
>
140dp
</dimen>
<!-- ChatRoom -->
<dimen
name=
"chat_item_top_and_bottom_padding"
>
12dp
</dimen>
<!-- Emoji -->
<!-- Emoji -->
<dimen
name=
"picker_padding_bottom"
>
16dp
</dimen>
<dimen
name=
"picker_padding_bottom"
>
16dp
</dimen>
<dimen
name=
"supposed_keyboard_height"
>
252dp
</dimen>
<dimen
name=
"supposed_keyboard_height"
>
252dp
</dimen>
...
...
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