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
ee16b416
Commit
ee16b416
authored
Nov 26, 2018
by
Filipe de Lima Brito
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' of github.com:RocketChat/Rocket.Chat.Android into new/licence-contactus
parents
1ba86e52
4c9ae11a
Changes
56
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
56 changed files
with
2277 additions
and
379 deletions
+2277
-379
12.json
app/schemas/chat.rocket.android.db.RCDatabase/12.json
+1087
-0
Analytics.kt
app/src/main/java/chat/rocket/android/analytics/Analytics.kt
+8
-1
AnalyticsManager.kt
...in/java/chat/rocket/android/analytics/AnalyticsManager.kt
+6
-0
BaseViewHolder.kt
...va/chat/rocket/android/chatroom/adapter/BaseViewHolder.kt
+4
-0
MessageReactionsAdapter.kt
...ocket/android/chatroom/adapter/MessageReactionsAdapter.kt
+8
-1
ChatRoomFragmentModule.kt
...chat/rocket/android/chatroom/di/ChatRoomFragmentModule.kt
+33
-0
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+113
-76
ChatRoomView.kt
...chat/rocket/android/chatroom/presentation/ChatRoomView.kt
+3
-10
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+62
-14
ReactionUiModel.kt
...a/chat/rocket/android/chatroom/uimodel/ReactionUiModel.kt
+3
-2
UiModelMapper.kt
...ava/chat/rocket/android/chatroom/uimodel/UiModelMapper.kt
+5
-2
RoomUiModelMapper.kt
...hat/rocket/android/chatrooms/adapter/RoomUiModelMapper.kt
+15
-6
RoomUiModel.kt
...hat/rocket/android/chatrooms/adapter/model/RoomUiModel.kt
+6
-2
ChatRoomsFragmentModule.kt
...at/rocket/android/chatrooms/di/ChatRoomsFragmentModule.kt
+4
-2
ChatRoomsRepository.kt
...t/android/chatrooms/infrastructure/ChatRoomsRepository.kt
+7
-3
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+24
-2
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+1
-2
ChatRoomsViewModel.kt
.../rocket/android/chatrooms/viewmodel/ChatRoomsViewModel.kt
+2
-2
DatabaseManager.kt
app/src/main/java/chat/rocket/android/db/DatabaseManager.kt
+94
-83
RCDatabase.kt
app/src/main/java/chat/rocket/android/db/RCDatabase.kt
+5
-2
ChatRoomEntity.kt
.../main/java/chat/rocket/android/db/model/ChatRoomEntity.kt
+6
-2
FavoriteMessagesPresenter.kt
...avoritemessages/presentation/FavoriteMessagesPresenter.kt
+2
-1
FilesPresenter.kt
.../chat/rocket/android/files/presentation/FilesPresenter.kt
+1
-0
MembersPresenter.kt
...t/rocket/android/members/presentation/MembersPresenter.kt
+2
-1
PinnedMessagesPresenter.kt
...id/pinnedmessages/presentation/PinnedMessagesPresenter.kt
+2
-1
PushManager.kt
app/src/main/java/chat/rocket/android/push/PushManager.kt
+2
-5
ConnectionManager.kt
...ocket/android/server/infraestructure/ConnectionManager.kt
+22
-0
DatabaseMessageMapper.kt
...t/android/server/infraestructure/DatabaseMessageMapper.kt
+7
-34
DatabaseMessagesRepository.kt
...roid/server/infraestructure/DatabaseMessagesRepository.kt
+30
-17
PasswordPresenter.kt
...droid/settings/password/presentation/PasswordPresenter.kt
+5
-1
SettingsFragment.kt
.../java/chat/rocket/android/settings/ui/SettingsFragment.kt
+22
-11
IO.kt
app/src/main/java/chat/rocket/android/util/IO.kt
+29
-0
emoji_image_row_item.xml
app/src/main/res/layout/emoji_image_row_item.xml
+14
-0
emoji_row_item.xml
app/src/main/res/layout/emoji_row_item.xml
+12
-0
reaction_praises_list_item.xml
app/src/main/res/layout/reaction_praises_list_item.xml
+35
-0
strings.xml
app/src/main/res/values-de/strings.xml
+13
-4
strings.xml
app/src/main/res/values-es/strings.xml
+11
-4
strings.xml
app/src/main/res/values-fr/strings.xml
+12
-5
strings.xml
app/src/main/res/values-hi-rIN/strings.xml
+13
-5
strings.xml
app/src/main/res/values-it/strings.xml
+321
-0
strings.xml
app/src/main/res/values-ja/strings.xml
+15
-9
strings.xml
app/src/main/res/values-pt-rBR/strings.xml
+13
-6
strings.xml
app/src/main/res/values-ru-rRU/strings.xml
+13
-5
strings.xml
app/src/main/res/values-tr/strings.xml
+12
-6
strings.xml
app/src/main/res/values-uk/strings.xml
+12
-4
defaults.xml
app/src/main/res/values/defaults.xml
+1
-0
strings.xml
app/src/main/res/values/strings.xml
+11
-4
AnswersAnalytics.kt
...ay/java/chat/rocket/android/analytics/AnswersAnalytics.kt
+7
-0
GoogleAnalyticsForFirebase.kt
...at/rocket/android/analytics/GoogleAnalyticsForFirebase.kt
+5
-0
FirebaseMessagingService.kt
...java/chat/rocket/android/push/FirebaseMessagingService.kt
+7
-3
EmojiKeyboardPopup.kt
...main/java/chat/rocket/android/emoji/EmojiKeyboardPopup.kt
+29
-38
EmojiReactionListener.kt
...n/java/chat/rocket/android/emoji/EmojiReactionListener.kt
+11
-1
bg_skin_tone.xml
emoji/src/main/res/drawable/bg_skin_tone.xml
+3
-1
dialog_skin_tone_chooser.xml
emoji/src/main/res/layout/dialog_skin_tone_chooser.xml
+85
-0
emoji_keyboard.xml
emoji/src/main/res/layout/emoji_keyboard.xml
+1
-1
strings.xml
emoji/src/main/res/values/strings.xml
+1
-0
No files found.
app/schemas/chat.rocket.android.db.RCDatabase/12.json
0 → 100644
View file @
ee16b416
This diff is collapsed.
Click to expand it.
app/src/main/java/chat/rocket/android/analytics/Analytics.kt
View file @
ee16b416
...
@@ -61,7 +61,14 @@ interface Analytics {
...
@@ -61,7 +61,14 @@ interface Analytics {
fun
logServerSwitch
(
serverUrl
:
String
,
serverCount
:
Int
)
{}
fun
logServerSwitch
(
serverUrl
:
String
,
serverCount
:
Int
)
{}
/**
/**
* Logs the admin opening.
* Logs the admin opening
event
.
*/
*/
fun
logOpenAdmin
()
{}
fun
logOpenAdmin
()
{}
/**
* Logs the reset password event.
*
* @param resetPasswordSucceeded True if successful reset password, false otherwise.
*/
fun
logResetPassword
(
resetPasswordSucceeded
:
Boolean
)
{}
}
}
app/src/main/java/chat/rocket/android/analytics/AnalyticsManager.kt
View file @
ee16b416
...
@@ -70,4 +70,10 @@ class AnalyticsManager @Inject constructor(
...
@@ -70,4 +70,10 @@ class AnalyticsManager @Inject constructor(
analytics
.
forEach
{
it
.
logOpenAdmin
()
}
analytics
.
forEach
{
it
.
logOpenAdmin
()
}
}
}
}
}
fun
logResetPassword
(
resetPasswordSucceeded
:
Boolean
)
{
if
(
analyticsTrackingInteractor
.
get
())
{
analytics
.
forEach
{
it
.
logResetPassword
(
resetPasswordSucceeded
)
}
}
}
}
}
app/src/main/java/chat/rocket/android/chatroom/adapter/BaseViewHolder.kt
View file @
ee16b416
...
@@ -61,6 +61,10 @@ abstract class BaseViewHolder<T : BaseUiModel<*>>(
...
@@ -61,6 +61,10 @@ abstract class BaseViewHolder<T : BaseUiModel<*>>(
reactionListener
?.
onReactionAdded
(
messageId
,
emoji
)
reactionListener
?.
onReactionAdded
(
messageId
,
emoji
)
}
}
}
}
override
fun
onReactionLongClicked
(
shortname
:
String
,
isCustom
:
Boolean
,
url
:
String
?,
usernames
:
List
<
String
>)
{
reactionListener
?.
onReactionLongClicked
(
shortname
,
isCustom
,
url
,
usernames
)
}
}
}
val
context
=
itemView
.
context
val
context
=
itemView
.
context
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/MessageReactionsAdapter.kt
View file @
ee16b416
...
@@ -75,7 +75,7 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
...
@@ -75,7 +75,7 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
class
ReactionViewHolder
(
class
ReactionViewHolder
(
view
:
View
,
view
:
View
,
private
val
listener
:
EmojiReactionListener
?
private
val
listener
:
EmojiReactionListener
?
)
:
RecyclerView
.
ViewHolder
(
view
),
View
.
OnClickListener
{
)
:
RecyclerView
.
ViewHolder
(
view
),
View
.
OnClickListener
,
View
.
OnLongClickListener
{
@Inject
@Inject
lateinit
var
localRepository
:
LocalRepository
lateinit
var
localRepository
:
LocalRepository
...
@@ -121,6 +121,8 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
...
@@ -121,6 +121,8 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
view_flipper_reaction
.
setOnClickListener
(
this
@ReactionViewHolder
)
view_flipper_reaction
.
setOnClickListener
(
this
@ReactionViewHolder
)
text_count
.
setOnClickListener
(
this
@ReactionViewHolder
)
text_count
.
setOnClickListener
(
this
@ReactionViewHolder
)
view_flipper_reaction
.
setOnLongClickListener
(
this
@ReactionViewHolder
)
text_count
.
setOnLongClickListener
(
this
@ReactionViewHolder
)
}
}
}
}
...
@@ -132,6 +134,11 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
...
@@ -132,6 +134,11 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
}
}
}
}
}
}
override
fun
onLongClick
(
v
:
View
?):
Boolean
{
listener
?.
onReactionLongClicked
(
reaction
.
shortname
,
reaction
.
isCustom
,
reaction
.
url
,
reaction
.
usernames
)
return
true
}
}
}
class
AddReactionViewHolder
(
class
AddReactionViewHolder
(
...
...
app/src/main/java/chat/rocket/android/chatroom/di/ChatRoomFragmentModule.kt
View file @
ee16b416
package
chat.rocket.android.chatroom.di
package
chat.rocket.android.chatroom.di
import
android.app.Application
import
androidx.lifecycle.LifecycleOwner
import
androidx.lifecycle.LifecycleOwner
import
chat.rocket.android.chatroom.presentation.ChatRoomView
import
chat.rocket.android.chatroom.presentation.ChatRoomView
import
chat.rocket.android.chatroom.ui.ChatRoomFragment
import
chat.rocket.android.chatroom.ui.ChatRoomFragment
import
chat.rocket.android.chatrooms.adapter.RoomUiModelMapper
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerFragment
import
chat.rocket.android.dagger.scope.PerFragment
import
chat.rocket.android.db.ChatRoomDao
import
chat.rocket.android.db.ChatRoomDao
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.db.DatabaseManagerFactory
import
chat.rocket.android.db.DatabaseManagerFactory
import
chat.rocket.android.db.UserDao
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetCurrentUserInteractor
import
chat.rocket.android.server.domain.PermissionsInteractor
import
chat.rocket.android.server.domain.SettingsRepository
import
chat.rocket.android.server.domain.TokenRepository
import
dagger.Module
import
dagger.Module
import
dagger.Provides
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
import
kotlinx.coroutines.experimental.Job
...
@@ -42,4 +49,30 @@ class ChatRoomFragmentModule {
...
@@ -42,4 +49,30 @@ class ChatRoomFragmentModule {
@Provides
@Provides
@PerFragment
@PerFragment
fun
provideChatRoomDao
(
manager
:
DatabaseManager
):
ChatRoomDao
=
manager
.
chatRoomDao
()
fun
provideChatRoomDao
(
manager
:
DatabaseManager
):
ChatRoomDao
=
manager
.
chatRoomDao
()
@Provides
@PerFragment
fun
provideUserDao
(
manager
:
DatabaseManager
):
UserDao
=
manager
.
userDao
()
@Provides
@PerFragment
fun
provideGetCurrentUserInteractor
(
tokenRepository
:
TokenRepository
,
@Named
(
"currentServer"
)
serverUrl
:
String
,
userDao
:
UserDao
):
GetCurrentUserInteractor
{
return
GetCurrentUserInteractor
(
tokenRepository
,
serverUrl
,
userDao
)
}
@Provides
@PerFragment
fun
provideRoomMapper
(
context
:
Application
,
repository
:
SettingsRepository
,
userInteractor
:
GetCurrentUserInteractor
,
@Named
(
"currentServer"
)
serverUrl
:
String
,
permissionsInteractor
:
PermissionsInteractor
):
RoomUiModelMapper
{
return
RoomUiModelMapper
(
context
,
repository
.
get
(
serverUrl
),
userInteractor
,
serverUrl
,
permissionsInteractor
)
}
}
}
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
ee16b416
...
@@ -15,6 +15,7 @@ import chat.rocket.android.chatroom.uimodel.suggestion.ChatRoomSuggestionUiModel
...
@@ -15,6 +15,7 @@ import chat.rocket.android.chatroom.uimodel.suggestion.ChatRoomSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.CommandSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.CommandSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.EmojiSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.EmojiSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.PeopleSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.PeopleSuggestionUiModel
import
chat.rocket.android.chatrooms.adapter.RoomUiModelMapper
import
chat.rocket.android.core.behaviours.showMessage
import
chat.rocket.android.core.behaviours.showMessage
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.db.DatabaseManager
...
@@ -34,11 +35,11 @@ import chat.rocket.android.server.domain.uploadMimeTypeFilter
...
@@ -34,11 +35,11 @@ import chat.rocket.android.server.domain.uploadMimeTypeFilter
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.state
import
chat.rocket.android.server.infraestructure.state
import
chat.rocket.android.util.extension.compressImageAndGetByteArray
import
chat.rocket.android.util.extension.getByteArray
import
chat.rocket.android.util.extension.getByteArray
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.getBitmpap
import
chat.rocket.android.util.extensions.exhaustive
import
chat.rocket.android.util.retryDB
import
chat.rocket.android.util.retryIO
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.RoomType
import
chat.rocket.common.model.RoomType
...
@@ -74,6 +75,7 @@ import chat.rocket.core.model.ChatRoom
...
@@ -74,6 +75,7 @@ import chat.rocket.core.model.ChatRoom
import
chat.rocket.core.model.ChatRoomRole
import
chat.rocket.core.model.ChatRoomRole
import
chat.rocket.core.model.Command
import
chat.rocket.core.model.Command
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Room
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.DefaultDispatcher
import
kotlinx.coroutines.experimental.DefaultDispatcher
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.android.UI
...
@@ -82,7 +84,6 @@ import kotlinx.coroutines.experimental.launch
...
@@ -82,7 +84,6 @@ import kotlinx.coroutines.experimental.launch
import
kotlinx.coroutines.experimental.withContext
import
kotlinx.coroutines.experimental.withContext
import
org.threeten.bp.Instant
import
org.threeten.bp.Instant
import
timber.log.Timber
import
timber.log.Timber
import
java.io.InputStream
import
java.util.*
import
java.util.*
import
javax.inject.Inject
import
javax.inject.Inject
...
@@ -98,6 +99,7 @@ class ChatRoomPresenter @Inject constructor(
...
@@ -98,6 +99,7 @@ class ChatRoomPresenter @Inject constructor(
private
val
analyticsManager
:
AnalyticsManager
,
private
val
analyticsManager
:
AnalyticsManager
,
private
val
userHelper
:
UserHelper
,
private
val
userHelper
:
UserHelper
,
private
val
mapper
:
UiModelMapper
,
private
val
mapper
:
UiModelMapper
,
private
val
roomMapper
:
RoomUiModelMapper
,
private
val
jobSchedulerInteractor
:
JobSchedulerInteractor
,
private
val
jobSchedulerInteractor
:
JobSchedulerInteractor
,
private
val
messageHelper
:
MessageHelper
,
private
val
messageHelper
:
MessageHelper
,
private
val
dbManager
:
DatabaseManager
,
private
val
dbManager
:
DatabaseManager
,
...
@@ -120,6 +122,7 @@ class ChatRoomPresenter @Inject constructor(
...
@@ -120,6 +122,7 @@ class ChatRoomPresenter @Inject constructor(
private
var
typingStatusSubscriptionId
:
String
?
=
null
private
var
typingStatusSubscriptionId
:
String
?
=
null
private
var
lastState
=
manager
.
state
private
var
lastState
=
manager
.
state
private
var
typingStatusList
=
arrayListOf
<
String
>()
private
var
typingStatusList
=
arrayListOf
<
String
>()
private
val
roomChangesChannel
=
Channel
<
Room
>(
Channel
.
CONFLATED
)
fun
setupChatRoom
(
fun
setupChatRoom
(
roomId
:
String
,
roomId
:
String
,
...
@@ -127,7 +130,7 @@ class ChatRoomPresenter @Inject constructor(
...
@@ -127,7 +130,7 @@ class ChatRoomPresenter @Inject constructor(
roomType
:
String
,
roomType
:
String
,
chatRoomMessage
:
String
?
=
null
chatRoomMessage
:
String
?
=
null
)
{
)
{
launch
UI
(
strategy
)
{
launch
(
CommonPool
+
strategy
.
jobs
)
{
try
{
try
{
chatRoles
=
if
(
roomTypeOf
(
roomType
)
!
is
RoomType
.
DirectMessage
)
{
chatRoles
=
if
(
roomTypeOf
(
roomType
)
!
is
RoomType
.
DirectMessage
)
{
client
.
chatRoomRoles
(
roomType
=
roomTypeOf
(
roomType
),
roomName
=
roomName
)
client
.
chatRoomRoles
(
roomType
=
roomTypeOf
(
roomType
),
roomName
=
roomName
)
...
@@ -137,13 +140,21 @@ class ChatRoomPresenter @Inject constructor(
...
@@ -137,13 +140,21 @@ class ChatRoomPresenter @Inject constructor(
chatRoles
=
emptyList
()
chatRoles
=
emptyList
()
}
finally
{
}
finally
{
// User has at least an 'owner' or 'moderator' role.
// User has at least an 'owner' or 'moderator' role.
val
userCanMod
=
isOwnerOrMod
()
val
canModerate
=
isOwnerOrMod
()
// Can post anyway if has the 'post-readonly' permission on server.
// Can post anyway if has the 'post-readonly' permission on server.
val
userCanPost
=
userCanMod
||
permissions
.
canPostToReadOnlyChannels
()
val
room
=
dbManager
.
getRoom
(
roomId
)
chatIsBroadcast
=
dbManager
.
getRoom
(
roomId
)
?.
chatRoom
?.
run
{
room
?.
let
{
broadcast
chatIsBroadcast
=
it
.
chatRoom
.
broadcast
?:
false
}
?:
false
val
roomUiModel
=
roomMapper
.
map
(
it
,
true
)
view
.
onRoomUpdated
(
userCanPost
,
chatIsBroadcast
,
userCanMod
)
launchUI
(
strategy
)
{
view
.
onRoomUpdated
(
roomUiModel
=
roomUiModel
.
copy
(
broadcast
=
chatIsBroadcast
,
canModerate
=
canModerate
,
writable
=
roomUiModel
.
writable
||
canModerate
))
}
}
loadMessages
(
roomId
,
roomType
,
clearDataSet
=
true
)
loadMessages
(
roomId
,
roomType
,
clearDataSet
=
true
)
chatRoomMessage
?.
let
{
messageHelper
.
messageIdFromPermalink
(
it
)
}
chatRoomMessage
?.
let
{
messageHelper
.
messageIdFromPermalink
(
it
)
}
?.
let
{
messageId
->
?.
let
{
messageId
->
...
@@ -155,10 +166,26 @@ class ChatRoomPresenter @Inject constructor(
...
@@ -155,10 +166,26 @@ class ChatRoomPresenter @Inject constructor(
true
true
)
)
}
}
subscribeRoomChanges
()
}
}
}
private
suspend
fun
subscribeRoomChanges
()
{
chatRoomId
?.
let
{
manager
.
addRoomChannel
(
it
,
roomChangesChannel
)
for
(
room
in
roomChangesChannel
)
{
dbManager
.
getRoom
(
room
.
id
)
?.
let
{
view
.
onRoomUpdated
(
roomMapper
.
map
(
chatRoom
=
it
,
showLastMessage
=
true
))
}
}
}
}
}
}
}
private
fun
unsubscribeRoomChanges
()
{
chatRoomId
?.
let
{
manager
.
removeRoomChannel
(
it
)
}
}
private
fun
isOwnerOrMod
():
Boolean
{
private
fun
isOwnerOrMod
():
Boolean
{
return
chatRoles
.
firstOrNull
{
it
.
user
.
username
==
currentLoggedUsername
}
?.
roles
?.
any
{
return
chatRoles
.
firstOrNull
{
it
.
user
.
username
==
currentLoggedUsername
}
?.
roles
?.
any
{
it
==
"owner"
||
it
==
"moderator"
it
==
"owner"
||
it
==
"moderator"
...
@@ -901,7 +928,8 @@ class ChatRoomPresenter @Inject constructor(
...
@@ -901,7 +928,8 @@ class ChatRoomPresenter @Inject constructor(
// TODO: move this to new interactor or FetchChatRoomsInteractor?
// TODO: move this to new interactor or FetchChatRoomsInteractor?
private
suspend
fun
getChatRoomAsync
(
roomId
:
String
):
ChatRoom
?
=
withContext
(
CommonPool
)
{
private
suspend
fun
getChatRoomAsync
(
roomId
:
String
):
ChatRoom
?
=
withContext
(
CommonPool
)
{
return
@withContext
dbManager
.
chatRoomDao
().
get
(
roomId
)
?.
let
{
retryDB
(
"getRoom($roomId)"
)
{
dbManager
.
chatRoomDao
().
get
(
roomId
)
?.
let
{
with
(
it
.
chatRoom
)
{
with
(
it
.
chatRoom
)
{
ChatRoom
(
ChatRoom
(
id
=
id
,
id
=
id
,
...
@@ -934,10 +962,12 @@ class ChatRoomPresenter @Inject constructor(
...
@@ -934,10 +962,12 @@ class ChatRoomPresenter @Inject constructor(
}
}
}
}
}
}
}
// TODO: move this to new interactor or FetchChatRoomsInteractor?
// TODO: move this to new interactor or FetchChatRoomsInteractor?
private
suspend
fun
getChatRoomsAsync
(
name
:
String
?
=
null
):
List
<
ChatRoom
>
=
withContext
(
CommonPool
)
{
private
suspend
fun
getChatRoomsAsync
(
name
:
String
?
=
null
):
List
<
ChatRoom
>
=
withContext
(
CommonPool
)
{
return
@withContext
dbManager
.
chatRoomDao
().
getAllSync
().
filter
{
retryDB
(
"getAllSync()"
)
{
dbManager
.
chatRoomDao
().
getAllSync
().
filter
{
if
(
name
==
null
)
{
if
(
name
==
null
)
{
return
@filter
true
return
@filter
true
}
}
...
@@ -975,13 +1005,19 @@ class ChatRoomPresenter @Inject constructor(
...
@@ -975,13 +1005,19 @@ class ChatRoomPresenter @Inject constructor(
}
}
}
}
}
}
}
fun
joinChat
(
chatRoomId
:
String
)
{
fun
joinChat
(
chatRoomId
:
String
)
{
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
try
{
try
{
retryIO
(
"joinChat($chatRoomId)"
)
{
client
.
joinChat
(
chatRoomId
)
}
retryIO
(
"joinChat($chatRoomId)"
)
{
client
.
joinChat
(
chatRoomId
)
}
val
canPost
=
permissions
.
canPostToReadOnlyChannels
()
val
canPost
=
permissions
.
canPostToReadOnlyChannels
()
view
.
onJoined
(
canPost
)
dbManager
.
getRoom
(
chatRoomId
)
?.
let
{
val
roomUiModel
=
roomMapper
.
map
(
it
,
true
).
copy
(
writable
=
canPost
)
view
.
onJoined
(
roomUiModel
=
roomUiModel
)
view
.
onRoomUpdated
(
roomUiModel
=
roomUiModel
)
}
}
catch
(
ex
:
RocketChatException
)
{
}
catch
(
ex
:
RocketChatException
)
{
Timber
.
e
(
ex
)
Timber
.
e
(
ex
)
}
}
...
@@ -1151,6 +1187,7 @@ class ChatRoomPresenter @Inject constructor(
...
@@ -1151,6 +1187,7 @@ class ChatRoomPresenter @Inject constructor(
}
}
fun
disconnect
()
{
fun
disconnect
()
{
unsubscribeRoomChanges
()
unsubscribeTypingStatus
()
unsubscribeTypingStatus
()
if
(
chatRoomId
!=
null
)
{
if
(
chatRoomId
!=
null
)
{
unsubscribeMessages
(
chatRoomId
.
toString
())
unsubscribeMessages
(
chatRoomId
.
toString
())
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt
View file @
ee16b416
...
@@ -5,6 +5,7 @@ import chat.rocket.android.chatroom.uimodel.suggestion.ChatRoomSuggestionUiModel
...
@@ -5,6 +5,7 @@ import chat.rocket.android.chatroom.uimodel.suggestion.ChatRoomSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.CommandSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.CommandSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.EmojiSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.EmojiSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.PeopleSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.PeopleSuggestionUiModel
import
chat.rocket.android.chatrooms.adapter.model.RoomUiModel
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.core.internal.realtime.socket.model.State
import
chat.rocket.core.internal.realtime.socket.model.State
...
@@ -131,12 +132,7 @@ interface ChatRoomView : LoadingView, MessageView {
...
@@ -131,12 +132,7 @@ interface ChatRoomView : LoadingView, MessageView {
fun
populateEmojiSuggestions
(
emojis
:
List
<
EmojiSuggestionUiModel
>)
fun
populateEmojiSuggestions
(
emojis
:
List
<
EmojiSuggestionUiModel
>)
/**
fun
onJoined
(
roomUiModel
:
RoomUiModel
)
* This user has joined the chat callback.
*
* @param userCanPost Whether the user can post a message or not.
*/
fun
onJoined
(
userCanPost
:
Boolean
)
fun
showReactionsPopup
(
messageId
:
String
)
fun
showReactionsPopup
(
messageId
:
String
)
...
@@ -147,9 +143,6 @@ interface ChatRoomView : LoadingView, MessageView {
...
@@ -147,9 +143,6 @@ interface ChatRoomView : LoadingView, MessageView {
*/
*/
fun
populateCommandSuggestions
(
commands
:
List
<
CommandSuggestionUiModel
>)
fun
populateCommandSuggestions
(
commands
:
List
<
CommandSuggestionUiModel
>)
/**
fun
onRoomUpdated
(
roomUiModel
:
RoomUiModel
)
* Communicate whether it's a broadcast channel and if current user can post to it.
*/
fun
onRoomUpdated
(
userCanPost
:
Boolean
,
channelIsBroadcast
:
Boolean
,
userCanMod
:
Boolean
)
}
}
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
ee16b416
...
@@ -51,6 +51,7 @@ import chat.rocket.android.chatroom.uimodel.suggestion.ChatRoomSuggestionUiModel
...
@@ -51,6 +51,7 @@ import chat.rocket.android.chatroom.uimodel.suggestion.ChatRoomSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.CommandSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.CommandSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.EmojiSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.EmojiSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.PeopleSuggestionUiModel
import
chat.rocket.android.chatroom.uimodel.suggestion.PeopleSuggestionUiModel
import
chat.rocket.android.chatrooms.adapter.model.RoomUiModel
import
chat.rocket.android.draw.main.ui.DRAWING_BYTE_ARRAY_EXTRA_DATA
import
chat.rocket.android.draw.main.ui.DRAWING_BYTE_ARRAY_EXTRA_DATA
import
chat.rocket.android.draw.main.ui.DrawingActivity
import
chat.rocket.android.draw.main.ui.DrawingActivity
import
chat.rocket.android.emoji.ComposerEditText
import
chat.rocket.android.emoji.ComposerEditText
...
@@ -60,6 +61,7 @@ import chat.rocket.android.emoji.EmojiKeyboardPopup
...
@@ -60,6 +61,7 @@ import chat.rocket.android.emoji.EmojiKeyboardPopup
import
chat.rocket.android.emoji.EmojiParser
import
chat.rocket.android.emoji.EmojiParser
import
chat.rocket.android.emoji.EmojiPickerPopup
import
chat.rocket.android.emoji.EmojiPickerPopup
import
chat.rocket.android.emoji.EmojiReactionListener
import
chat.rocket.android.emoji.EmojiReactionListener
import
chat.rocket.android.emoji.internal.GlideApp
import
chat.rocket.android.emoji.internal.isCustom
import
chat.rocket.android.emoji.internal.isCustom
import
chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import
chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import
chat.rocket.android.helper.ImageHelper
import
chat.rocket.android.helper.ImageHelper
...
@@ -84,6 +86,8 @@ import dagger.android.support.AndroidSupportInjection
...
@@ -84,6 +86,8 @@ import dagger.android.support.AndroidSupportInjection
import
io.reactivex.Observable
import
io.reactivex.Observable
import
io.reactivex.disposables.CompositeDisposable
import
io.reactivex.disposables.CompositeDisposable
import
io.reactivex.disposables.Disposable
import
io.reactivex.disposables.Disposable
import
kotlinx.android.synthetic.main.emoji_image_row_item.*
import
kotlinx.android.synthetic.main.emoji_row_item.*
import
kotlinx.android.synthetic.main.fragment_chat_room.*
import
kotlinx.android.synthetic.main.fragment_chat_room.*
import
kotlinx.android.synthetic.main.message_attachment_options.*
import
kotlinx.android.synthetic.main.message_attachment_options.*
import
kotlinx.android.synthetic.main.message_composer.*
import
kotlinx.android.synthetic.main.message_composer.*
...
@@ -91,6 +95,7 @@ import kotlinx.android.synthetic.main.message_list.*
...
@@ -91,6 +95,7 @@ import kotlinx.android.synthetic.main.message_list.*
import
timber.log.Timber
import
timber.log.Timber
import
java.io.File
import
java.io.File
import
java.io.IOException
import
java.io.IOException
import
kotlinx.android.synthetic.main.reaction_praises_list_item.*
import
java.util.concurrent.TimeUnit
import
java.util.concurrent.TimeUnit
import
java.util.concurrent.atomic.AtomicInteger
import
java.util.concurrent.atomic.AtomicInteger
import
javax.inject.Inject
import
javax.inject.Inject
...
@@ -397,17 +402,14 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
...
@@ -397,17 +402,14 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
empty_chat_view
.
isVisible
=
adapter
.
itemCount
==
0
empty_chat_view
.
isVisible
=
adapter
.
itemCount
==
0
}
}
override
fun
onRoomUpdated
(
override
fun
onRoomUpdated
(
roomUiModel
:
RoomUiModel
)
{
userCanPost
:
Boolean
,
channelIsBroadcast
:
Boolean
,
userCanMod
:
Boolean
)
{
// TODO: We should rely solely on the user being able to post, but we cannot guarantee
// TODO: We should rely solely on the user being able to post, but we cannot guarantee
// that the "(channels|groups).roles" endpoint is supported by the server in use.
// that the "(channels|groups).roles" endpoint is supported by the server in use.
ui
{
ui
{
setupMessageComposer
(
userCanPost
)
setupToolbar
(
roomUiModel
.
name
.
toString
())
isBroadcastChannel
=
channelIsBroadcast
setupMessageComposer
(
roomUiModel
)
if
(
isBroadcastChannel
&&
!
userCanMod
)
{
isBroadcastChannel
=
roomUiModel
.
broadcast
if
(
isBroadcastChannel
&&
!
roomUiModel
.
canModerate
)
{
disableMenu
=
true
disableMenu
=
true
activity
?.
invalidateOptionsMenu
()
activity
?.
invalidateOptionsMenu
()
}
}
...
@@ -544,7 +546,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
...
@@ -544,7 +546,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
ui
{
ui
{
button_send
.
isEnabled
=
true
button_send
.
isEnabled
=
true
text_message
.
isEnabled
=
true
text_message
.
isEnabled
=
true
clearMessageComposition
(
true
)
}
}
}
}
...
@@ -611,7 +612,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
...
@@ -611,7 +612,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
}
}
}
override
fun
showGenericErrorMessage
(){
override
fun
showGenericErrorMessage
()
{
ui
{
ui
{
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
}
}
...
@@ -688,6 +689,44 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
...
@@ -688,6 +689,44 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter
.
react
(
messageId
,
emoji
.
shortname
)
presenter
.
react
(
messageId
,
emoji
.
shortname
)
}
}
override
fun
onReactionLongClicked
(
shortname
:
String
,
isCustom
:
Boolean
,
url
:
String
?,
usernames
:
List
<
String
>)
{
val
layout
=
LayoutInflater
.
from
(
requireContext
()).
inflate
(
R
.
layout
.
reaction_praises_list_item
,
null
)
val
dialog
=
AlertDialog
.
Builder
(
requireContext
())
.
setView
(
layout
)
.
setCancelable
(
true
)
with
(
layout
)
{
view_flipper
.
displayedChild
=
if
(
isCustom
)
1
else
0
if
(
isCustom
&&
url
!=
null
)
{
val
glideRequest
=
if
(
url
.
endsWith
(
"gif"
,
true
))
{
GlideApp
.
with
(
requireContext
()).
asGif
()
}
else
{
GlideApp
.
with
(
requireContext
()).
asBitmap
()
}
glideRequest
.
load
(
url
).
into
(
emoji_image_view
)
}
else
{
emoji_view
.
text
=
EmojiParser
.
parse
(
requireContext
(),
shortname
)
}
var
listing
=
""
if
(
usernames
.
size
==
1
)
{
listing
=
usernames
.
first
()
}
else
{
usernames
.
forEachIndexed
{
index
,
username
->
listing
+=
if
(
index
==
usernames
.
size
-
1
)
"|$username"
else
"$username, "
}
listing
=
listing
.
replace
(
", |"
,
" ${requireContext().getString(R.string.msg_and)} "
)
}
text_view_usernames
.
text
=
requireContext
().
resources
.
getQuantityString
(
R
.
plurals
.
msg_reacted_with_
,
usernames
.
size
,
listing
,
shortname
)
dialog
.
show
()
}
}
override
fun
showReactionsPopup
(
messageId
:
String
)
{
override
fun
showReactionsPopup
(
messageId
:
String
)
{
ui
{
ui
{
val
emojiPickerPopup
=
EmojiPickerPopup
(
it
)
val
emojiPickerPopup
=
EmojiPickerPopup
(
it
)
...
@@ -748,12 +787,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
...
@@ -748,12 +787,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
}
}
}
override
fun
onJoined
(
userCanPost
:
Boolean
)
{
override
fun
onJoined
(
roomUiModel
:
RoomUiModel
)
{
ui
{
ui
{
input_container
.
isVisible
=
true
input_container
.
isVisible
=
true
button_join_chat
.
isVisible
=
false
button_join_chat
.
isVisible
=
false
isSubscribed
=
true
isSubscribed
=
true
setupMessageComposer
(
userCanPost
)
}
}
}
}
...
@@ -786,15 +824,25 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
...
@@ -786,15 +824,25 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
}
}
}
private
fun
setupMessageComposer
(
canPost
:
Boolean
)
{
private
fun
setupMessageComposer
(
roomUiModel
:
RoomUiModel
)
{
if
(
isReadOnly
&&
!
canPost
)
{
if
(
isReadOnly
||
!
roomUiModel
.
writable
)
{
text_room_is_read_only
.
isVisible
=
true
text_room_is_read_only
.
isVisible
=
true
input_container
.
isVisible
=
false
input_container
.
isVisible
=
false
text_room_is_read_only
.
setText
(
if
(
isReadOnly
)
{
R
.
string
.
msg_this_room_is_read_only
}
else
{
// Not a read-only channel but user has been muted.
R
.
string
.
msg_muted_on_this_channel
}
)
}
else
if
(!
isSubscribed
&&
roomTypeOf
(
chatRoomType
)
!
is
RoomType
.
DirectMessage
)
{
}
else
if
(!
isSubscribed
&&
roomTypeOf
(
chatRoomType
)
!
is
RoomType
.
DirectMessage
)
{
input_container
.
isVisible
=
false
input_container
.
isVisible
=
false
button_join_chat
.
isVisible
=
true
button_join_chat
.
isVisible
=
true
button_join_chat
.
setOnClickListener
{
presenter
.
joinChat
(
chatRoomId
)
}
button_join_chat
.
setOnClickListener
{
presenter
.
joinChat
(
chatRoomId
)
}
}
else
{
}
else
{
input_container
.
isVisible
=
true
text_room_is_read_only
.
isVisible
=
false
button_send
.
isVisible
=
false
button_send
.
isVisible
=
false
button_show_attachment_options
.
alpha
=
1f
button_show_attachment_options
.
alpha
=
1f
button_show_attachment_options
.
isVisible
=
true
button_show_attachment_options
.
isVisible
=
true
...
...
app/src/main/java/chat/rocket/android/chatroom/uimodel/ReactionUiModel.kt
View file @
ee16b416
...
@@ -6,5 +6,6 @@ data class ReactionUiModel(
...
@@ -6,5 +6,6 @@ data class ReactionUiModel(
val
unicode
:
CharSequence
,
val
unicode
:
CharSequence
,
val
count
:
Int
,
val
count
:
Int
,
val
usernames
:
List
<
String
>
=
emptyList
(),
val
usernames
:
List
<
String
>
=
emptyList
(),
var
url
:
String
?
=
null
var
url
:
String
?
=
null
,
val
isCustom
:
Boolean
=
false
)
)
app/src/main/java/chat/rocket/android/chatroom/uimodel/UiModelMapper.kt
View file @
ee16b416
...
@@ -19,6 +19,7 @@ import chat.rocket.android.dagger.scope.PerFragment
...
@@ -19,6 +19,7 @@ import chat.rocket.android.dagger.scope.PerFragment
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.emoji.EmojiParser
import
chat.rocket.android.emoji.EmojiParser
import
chat.rocket.android.emoji.EmojiRepository
import
chat.rocket.android.emoji.EmojiRepository
import
chat.rocket.android.emoji.internal.isCustom
import
chat.rocket.android.helper.MessageHelper
import
chat.rocket.android.helper.MessageHelper
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.helper.UserHelper
import
chat.rocket.android.helper.UserHelper
...
@@ -31,6 +32,7 @@ import chat.rocket.android.server.domain.messageReadReceiptEnabled
...
@@ -31,6 +32,7 @@ import chat.rocket.android.server.domain.messageReadReceiptEnabled
import
chat.rocket.android.server.domain.messageReadReceiptStoreUsers
import
chat.rocket.android.server.domain.messageReadReceiptStoreUsers
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.util.extension.orFalse
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.ifNotNullNorEmpty
import
chat.rocket.android.util.extensions.ifNotNullNorEmpty
import
chat.rocket.android.util.extensions.isNotNullNorEmpty
import
chat.rocket.android.util.extensions.isNotNullNorEmpty
...
@@ -469,7 +471,7 @@ class UiModelMapper @Inject constructor(
...
@@ -469,7 +471,7 @@ class UiModelMapper @Inject constructor(
val
list
=
mutableListOf
<
ReactionUiModel
>()
val
list
=
mutableListOf
<
ReactionUiModel
>()
val
customEmojis
=
EmojiRepository
.
getCustomEmojis
()
val
customEmojis
=
EmojiRepository
.
getCustomEmojis
()
it
.
getShortNames
().
forEach
{
shortname
->
it
.
getShortNames
().
forEach
{
shortname
->
val
usernames
=
it
.
getUsernames
(
shortname
)
?:
emptyList
()
val
usernames
=
it
.
getUsernames
(
shortname
)
.
orEmpty
()
val
count
=
usernames
.
size
val
count
=
usernames
.
size
val
custom
=
customEmojis
.
firstOrNull
{
emoji
->
emoji
.
shortname
==
shortname
}
val
custom
=
customEmojis
.
firstOrNull
{
emoji
->
emoji
.
shortname
==
shortname
}
list
.
add
(
list
.
add
(
...
@@ -478,7 +480,8 @@ class UiModelMapper @Inject constructor(
...
@@ -478,7 +480,8 @@ class UiModelMapper @Inject constructor(
unicode
=
EmojiParser
.
parse
(
context
,
shortname
),
unicode
=
EmojiParser
.
parse
(
context
,
shortname
),
count
=
count
,
count
=
count
,
usernames
=
usernames
,
usernames
=
usernames
,
url
=
custom
?.
url
)
url
=
custom
?.
url
,
isCustom
=
custom
!=
null
)
)
)
}
}
list
list
...
...
app/src/main/java/chat/rocket/android/chatrooms/adapter/RoomUiModelMapper.kt
View file @
ee16b416
...
@@ -8,9 +8,8 @@ import androidx.core.text.color
...
@@ -8,9 +8,8 @@ import androidx.core.text.color
import
chat.rocket.android.R
import
chat.rocket.android.R
import
chat.rocket.android.chatrooms.adapter.model.RoomUiModel
import
chat.rocket.android.chatrooms.adapter.model.RoomUiModel
import
chat.rocket.android.db.model.ChatRoom
import
chat.rocket.android.db.model.ChatRoom
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.checkIfMyself
import
chat.rocket.android.server.domain.GetCurrentUserInteractor
import
chat.rocket.android.server.domain.GetCurrentUserInteractor
import
chat.rocket.android.server.domain.PermissionsInteractor
import
chat.rocket.android.server.domain.PublicSettings
import
chat.rocket.android.server.domain.PublicSettings
import
chat.rocket.android.server.domain.showLastMessage
import
chat.rocket.android.server.domain.showLastMessage
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.server.domain.useRealName
...
@@ -30,7 +29,8 @@ class RoomUiModelMapper(
...
@@ -30,7 +29,8 @@ class RoomUiModelMapper(
private
val
context
:
Application
,
private
val
context
:
Application
,
private
val
settings
:
PublicSettings
,
private
val
settings
:
PublicSettings
,
private
val
userInteractor
:
GetCurrentUserInteractor
,
private
val
userInteractor
:
GetCurrentUserInteractor
,
private
val
serverUrl
:
String
private
val
serverUrl
:
String
,
private
val
permissions
:
PermissionsInteractor
)
{
)
{
private
val
nameUnreadColor
=
ContextCompat
.
getColor
(
context
,
R
.
color
.
colorPrimaryText
)
private
val
nameUnreadColor
=
ContextCompat
.
getColor
(
context
,
R
.
color
.
colorPrimaryText
)
private
val
nameColor
=
ContextCompat
.
getColor
(
context
,
R
.
color
.
colorSecondaryText
)
private
val
nameColor
=
ContextCompat
.
getColor
(
context
,
R
.
color
.
colorSecondaryText
)
...
@@ -97,7 +97,9 @@ class RoomUiModelMapper(
...
@@ -97,7 +97,9 @@ class RoomUiModelMapper(
avatar
=
serverUrl
.
avatarUrl
(
name
!!
,
isGroupOrChannel
=
true
),
avatar
=
serverUrl
.
avatarUrl
(
name
!!
,
isGroupOrChannel
=
true
),
lastMessage
=
if
(
showLastMessage
)
{
mapLastMessage
(
lastMessage
?.
sender
?.
id
,
lastMessage
?.
sender
?.
username
,
lastMessage
=
if
(
showLastMessage
)
{
mapLastMessage
(
lastMessage
?.
sender
?.
id
,
lastMessage
?.
sender
?.
username
,
lastMessage
?.
sender
?.
name
,
lastMessage
?.
message
,
lastMessage
?.
sender
?.
name
,
lastMessage
?.
message
,
isDirectMessage
=
type
is
RoomType
.
DirectMessage
)}
else
{
null
}
isDirectMessage
=
type
is
RoomType
.
DirectMessage
)}
else
{
null
},
muted
=
muted
.
orEmpty
(),
writable
=
isChannelWritable
(
muted
)
)
)
}
}
}
}
...
@@ -133,11 +135,18 @@ class RoomUiModelMapper(
...
@@ -133,11 +135,18 @@ class RoomUiModelMapper(
alert
=
isUnread
,
alert
=
isUnread
,
lastMessage
=
lastMessageMarkdown
,
lastMessage
=
lastMessageMarkdown
,
status
=
status
,
status
=
status
,
username
=
if
(
type
is
RoomType
.
DirectMessage
)
name
else
null
username
=
if
(
type
is
RoomType
.
DirectMessage
)
name
else
null
,
muted
=
muted
.
orEmpty
(),
writable
=
isChannelWritable
(
muted
)
)
)
}
}
}
}
private
fun
isChannelWritable
(
muted
:
List
<
String
>?):
Boolean
{
val
canWriteToReadOnlyChannels
=
permissions
.
canPostToReadOnlyChannels
()
return
canWriteToReadOnlyChannels
||
!
muted
.
orEmpty
().
contains
(
currentUser
?.
username
)
}
private
fun
roomType
(
type
:
String
):
String
{
private
fun
roomType
(
type
:
String
):
String
{
val
resources
=
context
.
resources
val
resources
=
context
.
resources
return
when
(
type
)
{
return
when
(
type
)
{
...
...
app/src/main/java/chat/rocket/android/chatrooms/adapter/model/RoomUiModel.kt
View file @
ee16b416
...
@@ -14,5 +14,9 @@ data class RoomUiModel(
...
@@ -14,5 +14,9 @@ data class RoomUiModel(
val
alert
:
Boolean
=
false
,
val
alert
:
Boolean
=
false
,
val
lastMessage
:
CharSequence
?
=
null
,
val
lastMessage
:
CharSequence
?
=
null
,
val
status
:
UserStatus
?
=
null
,
val
status
:
UserStatus
?
=
null
,
val
username
:
String
?
=
null
val
username
:
String
?
=
null
,
val
broadcast
:
Boolean
=
false
,
val
canModerate
:
Boolean
=
false
,
val
writable
:
Boolean
=
true
,
val
muted
:
List
<
String
>
=
emptyList
()
)
)
app/src/main/java/chat/rocket/android/chatrooms/di/ChatRoomsFragmentModule.kt
View file @
ee16b416
...
@@ -12,6 +12,7 @@ import chat.rocket.android.db.DatabaseManager
...
@@ -12,6 +12,7 @@ import chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.db.UserDao
import
chat.rocket.android.db.UserDao
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.GetCurrentUserInteractor
import
chat.rocket.android.server.domain.GetCurrentUserInteractor
import
chat.rocket.android.server.domain.PermissionsInteractor
import
chat.rocket.android.server.domain.PublicSettings
import
chat.rocket.android.server.domain.PublicSettings
import
chat.rocket.android.server.domain.SettingsRepository
import
chat.rocket.android.server.domain.SettingsRepository
import
chat.rocket.android.server.domain.TokenRepository
import
chat.rocket.android.server.domain.TokenRepository
...
@@ -88,9 +89,10 @@ class ChatRoomsFragmentModule {
...
@@ -88,9 +89,10 @@ class ChatRoomsFragmentModule {
context
:
Application
,
context
:
Application
,
repository
:
SettingsRepository
,
repository
:
SettingsRepository
,
userInteractor
:
GetCurrentUserInteractor
,
userInteractor
:
GetCurrentUserInteractor
,
@Named
(
"currentServer"
)
serverUrl
:
String
@Named
(
"currentServer"
)
serverUrl
:
String
,
permissionsInteractor
:
PermissionsInteractor
):
RoomUiModelMapper
{
):
RoomUiModelMapper
{
return
RoomUiModelMapper
(
context
,
repository
.
get
(
serverUrl
),
userInteractor
,
serverUrl
)
return
RoomUiModelMapper
(
context
,
repository
.
get
(
serverUrl
),
userInteractor
,
serverUrl
,
permissionsInteractor
)
}
}
@Provides
@Provides
...
...
app/src/main/java/chat/rocket/android/chatrooms/infrastructure/ChatRoomsRepository.kt
View file @
ee16b416
...
@@ -3,9 +3,12 @@ package chat.rocket.android.chatrooms.infrastructure
...
@@ -3,9 +3,12 @@ package chat.rocket.android.chatrooms.infrastructure
import
androidx.lifecycle.LiveData
import
androidx.lifecycle.LiveData
import
chat.rocket.android.db.ChatRoomDao
import
chat.rocket.android.db.ChatRoomDao
import
chat.rocket.android.db.model.ChatRoom
import
chat.rocket.android.db.model.ChatRoom
import
chat.rocket.android.util.retryDB
import
javax.inject.Inject
import
javax.inject.Inject
class
ChatRoomsRepository
@Inject
constructor
(
private
val
dao
:
ChatRoomDao
){
class
ChatRoomsRepository
@Inject
constructor
(
private
val
dao
:
ChatRoomDao
)
{
// TODO - check how to use retryDB here - suspend
fun
getChatRooms
(
order
:
Order
):
LiveData
<
List
<
ChatRoom
>>
{
fun
getChatRooms
(
order
:
Order
):
LiveData
<
List
<
ChatRoom
>>
{
return
when
(
order
)
{
return
when
(
order
)
{
Order
.
ACTIVITY
->
dao
.
getAll
()
Order
.
ACTIVITY
->
dao
.
getAll
()
...
@@ -15,9 +18,10 @@ class ChatRoomsRepository @Inject constructor(private val dao: ChatRoomDao){
...
@@ -15,9 +18,10 @@ class ChatRoomsRepository @Inject constructor(private val dao: ChatRoomDao){
}
}
}
}
fun
search
(
query
:
String
)
=
dao
.
searchSync
(
query
)
suspend
fun
search
(
query
:
String
)
=
retryDB
(
"roomSearch($query)"
)
{
dao
.
searchSync
(
query
)
}
fun
count
()
=
dao
.
count
()
suspend
fun
count
()
=
retryDB
(
"roomsCount"
)
{
dao
.
count
()
}
enum
class
Order
{
enum
class
Order
{
ACTIVITY
,
ACTIVITY
,
...
...
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
ee16b416
...
@@ -13,6 +13,7 @@ import chat.rocket.android.server.domain.useRealName
...
@@ -13,6 +13,7 @@ import chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.server.domain.useSpecialCharsOnRoom
import
chat.rocket.android.server.domain.useSpecialCharsOnRoom
import
chat.rocket.android.server.infraestructure.ConnectionManager
import
chat.rocket.android.server.infraestructure.ConnectionManager
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.retryDB
import
chat.rocket.android.util.retryIO
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.RoomType
import
chat.rocket.common.model.RoomType
...
@@ -41,11 +42,31 @@ class ChatRoomsPresenter @Inject constructor(
...
@@ -41,11 +42,31 @@ class ChatRoomsPresenter @Inject constructor(
private
val
client
=
manager
.
client
private
val
client
=
manager
.
client
private
val
settings
=
settingsRepository
.
get
(
currentServer
)
private
val
settings
=
settingsRepository
.
get
(
currentServer
)
fun
loadChatRoom
(
roomId
:
String
)
{
launchUI
(
strategy
)
{
view
.
showLoadingRoom
(
""
)
try
{
val
room
=
dbManager
.
getRoom
(
roomId
)
if
(
room
!=
null
)
{
loadChatRoom
(
room
.
chatRoom
,
true
)
}
else
{
Timber
.
d
(
"Error loading channel"
)
view
.
showGenericErrorMessage
()
}
}
catch
(
ex
:
Exception
)
{
Timber
.
d
(
ex
,
"Error loading channel"
)
view
.
showGenericErrorMessage
()
}
finally
{
view
.
hideLoadingRoom
()
}
}
}
fun
loadChatRoom
(
chatRoom
:
RoomUiModel
)
{
fun
loadChatRoom
(
chatRoom
:
RoomUiModel
)
{
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
view
.
showLoadingRoom
(
chatRoom
.
name
)
view
.
showLoadingRoom
(
chatRoom
.
name
)
try
{
try
{
val
room
=
dbManager
.
getRoom
(
chatRoom
.
id
)
val
room
=
retryDB
(
"getRoom(${chatRoom.id}"
)
{
dbManager
.
getRoom
(
chatRoom
.
id
)
}
if
(
room
!=
null
)
{
if
(
room
!=
null
)
{
loadChatRoom
(
room
.
chatRoom
,
true
)
loadChatRoom
(
room
.
chatRoom
,
true
)
}
else
{
}
else
{
...
@@ -56,7 +77,8 @@ class ChatRoomsPresenter @Inject constructor(
...
@@ -56,7 +77,8 @@ class ChatRoomsPresenter @Inject constructor(
type
=
type
.
toString
(),
type
=
type
.
toString
(),
name
=
username
?:
name
.
toString
(),
name
=
username
?:
name
.
toString
(),
fullname
=
name
.
toString
(),
fullname
=
name
.
toString
(),
open
=
open
open
=
open
,
muted
=
muted
)
)
loadChatRoom
(
entity
,
false
)
loadChatRoom
(
entity
,
false
)
}
}
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
ee16b416
...
@@ -84,8 +84,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
...
@@ -84,8 +84,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
if
(
bundle
!=
null
)
{
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
chatRoomId
?.
let
{
chatRoomId
?.
let
{
// TODO - bring back support to load a room from id.
presenter
.
loadChatRoom
(
it
)
//presenter.goToChatRoomWithId(it)
chatRoomId
=
null
chatRoomId
=
null
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/chatrooms/viewmodel/ChatRoomsViewModel.kt
View file @
ee16b416
...
@@ -27,7 +27,7 @@ import kotlinx.coroutines.experimental.launch
...
@@ -27,7 +27,7 @@ import kotlinx.coroutines.experimental.launch
import
kotlinx.coroutines.experimental.newSingleThreadContext
import
kotlinx.coroutines.experimental.newSingleThreadContext
import
kotlinx.coroutines.experimental.withContext
import
kotlinx.coroutines.experimental.withContext
import
timber.log.Timber
import
timber.log.Timber
import
java.
security.InvalidParameter
Exception
import
java.
lang.IllegalArgument
Exception
import
kotlin.coroutines.experimental.coroutineContext
import
kotlin.coroutines.experimental.coroutineContext
...
@@ -171,6 +171,6 @@ fun Query.asSortingOrder(): ChatRoomsRepository.Order {
...
@@ -171,6 +171,6 @@ fun Query.asSortingOrder(): ChatRoomsRepository.Order {
ChatRoomsRepository
.
Order
.
ACTIVITY
ChatRoomsRepository
.
Order
.
ACTIVITY
}
}
}
}
else
->
throw
I
nvalidParameter
Exception
(
"Should be ByName or ByActivity"
)
else
->
throw
I
llegalArgument
Exception
(
"Should be ByName or ByActivity"
)
}
}
}
}
app/src/main/java/chat/rocket/android/db/DatabaseManager.kt
View file @
ee16b416
...
@@ -19,6 +19,7 @@ import chat.rocket.android.util.extensions.exhaustive
...
@@ -19,6 +19,7 @@ import chat.rocket.android.util.extensions.exhaustive
import
chat.rocket.android.util.extensions.removeTrailingSlash
import
chat.rocket.android.util.extensions.removeTrailingSlash
import
chat.rocket.android.util.extensions.toEntity
import
chat.rocket.android.util.extensions.toEntity
import
chat.rocket.android.util.extensions.userId
import
chat.rocket.android.util.extensions.userId
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.model.BaseRoom
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
...
@@ -41,8 +42,7 @@ import timber.log.Timber
...
@@ -41,8 +42,7 @@ import timber.log.Timber
import
java.util.HashSet
import
java.util.HashSet
import
kotlin.system.measureTimeMillis
import
kotlin.system.measureTimeMillis
class
DatabaseManager
(
val
context
:
Application
,
class
DatabaseManager
(
val
context
:
Application
,
val
serverUrl
:
String
)
{
val
serverUrl
:
String
)
{
private
val
database
:
RCDatabase
=
androidx
.
room
.
Room
.
databaseBuilder
(
context
,
private
val
database
:
RCDatabase
=
androidx
.
room
.
Room
.
databaseBuilder
(
context
,
RCDatabase
::
class
.
java
,
serverUrl
.
databaseName
())
RCDatabase
::
class
.
java
,
serverUrl
.
databaseName
())
...
@@ -92,13 +92,15 @@ class DatabaseManager(val context: Application,
...
@@ -92,13 +92,15 @@ class DatabaseManager(val context: Application,
}
}
}
}
fun
logout
()
{
suspend
fun
logout
()
{
database
.
clearAllTables
()
retryDB
(
"clearAllTables"
)
{
database
.
clearAllTables
()
}
}
}
suspend
fun
getRoom
(
id
:
String
)
=
withContext
(
dbManagerContext
)
{
suspend
fun
getRoom
(
id
:
String
)
=
withContext
(
dbManagerContext
)
{
retryDB
(
"getRoom($id)"
)
{
chatRoomDao
().
get
(
id
)
chatRoomDao
().
get
(
id
)
}
}
}
fun
processUsersBatch
(
users
:
List
<
User
>)
{
fun
processUsersBatch
(
users
:
List
<
User
>)
{
launch
(
dbManagerContext
)
{
launch
(
dbManagerContext
)
{
...
@@ -124,11 +126,11 @@ class DatabaseManager(val context: Application,
...
@@ -124,11 +126,11 @@ class DatabaseManager(val context: Application,
val
toInsert
=
ArrayList
<
ChatRoomEntity
>(
batch
.
size
/
2
)
val
toInsert
=
ArrayList
<
ChatRoomEntity
>(
batch
.
size
/
2
)
val
toUpdate
=
ArrayList
<
ChatRoomEntity
>(
batch
.
size
)
val
toUpdate
=
ArrayList
<
ChatRoomEntity
>(
batch
.
size
)
batch
.
forEach
{
batch
.
forEach
{
when
(
it
.
type
)
{
when
(
it
.
type
)
{
is
Type
.
Removed
->
toRemove
.
add
(
removeChatRoom
(
it
.
data
))
is
Type
.
Removed
->
toRemove
.
add
(
removeChatRoom
(
it
.
data
))
is
Type
.
Inserted
->
insertChatRoom
(
it
.
data
)
?.
let
{
toInsert
.
add
(
it
)
}
is
Type
.
Inserted
->
insertChatRoom
(
it
.
data
)
?.
let
{
toInsert
.
add
(
it
)
}
is
Type
.
Updated
->
{
is
Type
.
Updated
->
{
when
(
it
.
data
)
{
when
(
it
.
data
)
{
is
Subscription
->
updateSubs
[(
it
.
data
as
Subscription
).
roomId
]
=
it
.
data
as
Subscription
is
Subscription
->
updateSubs
[(
it
.
data
as
Subscription
).
roomId
]
=
it
.
data
as
Subscription
is
Room
->
updateRooms
[(
it
.
data
as
Room
).
id
]
=
it
.
data
as
Room
is
Room
->
updateRooms
[(
it
.
data
as
Room
).
id
]
=
it
.
data
as
Room
}
}
...
@@ -152,7 +154,7 @@ class DatabaseManager(val context: Application,
...
@@ -152,7 +154,7 @@ class DatabaseManager(val context: Application,
fun
updateSelfUser
(
myself
:
Myself
)
{
fun
updateSelfUser
(
myself
:
Myself
)
{
launch
(
dbManagerContext
)
{
launch
(
dbManagerContext
)
{
val
user
=
userDao
().
getUser
(
myself
.
id
)
val
user
=
retryDB
(
"getUser(${myself.id})"
)
{
userDao
().
getUser
(
myself
.
id
)
}
val
entity
=
user
?.
copy
(
val
entity
=
user
?.
copy
(
name
=
myself
.
name
?:
user
.
name
,
name
=
myself
.
name
?:
user
.
name
,
username
=
myself
.
username
?:
user
.
username
,
username
=
myself
.
username
?:
user
.
username
,
...
@@ -329,14 +331,14 @@ class DatabaseManager(val context: Application,
...
@@ -329,14 +331,14 @@ class DatabaseManager(val context: Application,
}
}
private
fun
removeChatRoom
(
data
:
BaseRoom
):
String
{
private
fun
removeChatRoom
(
data
:
BaseRoom
):
String
{
return
when
(
data
)
{
return
when
(
data
)
{
is
Subscription
->
data
.
roomId
is
Subscription
->
data
.
roomId
else
->
data
.
id
else
->
data
.
id
}
}
}
}
private
suspend
fun
updateRoom
(
data
:
Room
):
ChatRoomEntity
?
{
private
suspend
fun
updateRoom
(
data
:
Room
):
ChatRoomEntity
?
{
return
chatRoomDao
().
get
(
data
.
id
)
?.
let
{
current
->
return
retryDB
(
"getChatRoom(${data.id})"
)
{
chatRoomDao
().
get
(
data
.
id
)
}
?.
let
{
current
->
with
(
data
)
{
with
(
data
)
{
val
chatRoom
=
current
.
chatRoom
val
chatRoom
=
current
.
chatRoom
...
@@ -351,7 +353,8 @@ class DatabaseManager(val context: Application,
...
@@ -351,7 +353,8 @@ class DatabaseManager(val context: Application,
updatedAt
=
updatedAt
?:
chatRoom
.
updatedAt
,
updatedAt
=
updatedAt
?:
chatRoom
.
updatedAt
,
lastMessageText
=
mapLastMessageText
(
lastMessage
),
lastMessageText
=
mapLastMessageText
(
lastMessage
),
lastMessageUserId
=
lastMessage
?.
sender
?.
id
,
lastMessageUserId
=
lastMessage
?.
sender
?.
id
,
lastMessageTimestamp
=
lastMessage
?.
timestamp
lastMessageTimestamp
=
lastMessage
?.
timestamp
,
muted
=
muted
)
)
}
}
}
}
...
@@ -373,7 +376,7 @@ class DatabaseManager(val context: Application,
...
@@ -373,7 +376,7 @@ class DatabaseManager(val context: Application,
context
.
getString
(
R
.
string
.
msg_sent_attachment
)
context
.
getString
(
R
.
string
.
msg_sent_attachment
)
private
suspend
fun
updateSubscription
(
data
:
Subscription
):
ChatRoomEntity
?
{
private
suspend
fun
updateSubscription
(
data
:
Subscription
):
ChatRoomEntity
?
{
return
chatRoomDao
().
get
(
data
.
roomId
)
?.
let
{
current
->
return
retryDB
(
"getRoom(${data.roomId}"
)
{
chatRoomDao
().
get
(
data
.
roomId
)
}
?.
let
{
current
->
with
(
data
)
{
with
(
data
)
{
val
userId
=
if
(
type
is
RoomType
.
DirectMessage
)
{
val
userId
=
if
(
type
is
RoomType
.
DirectMessage
)
{
...
@@ -389,7 +392,8 @@ class DatabaseManager(val context: Application,
...
@@ -389,7 +392,8 @@ class DatabaseManager(val context: Application,
id
=
roomId
,
id
=
roomId
,
subscriptionId
=
id
,
subscriptionId
=
id
,
type
=
type
.
toString
(),
type
=
type
.
toString
(),
name
=
name
?:
throw
NullPointerException
(),
// this should be filtered on the SDK
name
=
name
?:
throw
NullPointerException
(),
// this should be filtered on the SDK
fullname
=
fullName
?:
chatRoom
.
fullname
,
fullname
=
fullName
?:
chatRoom
.
fullname
,
userId
=
userId
?:
chatRoom
.
userId
,
userId
=
userId
?:
chatRoom
.
userId
,
readonly
=
readonly
?:
chatRoom
.
readonly
,
readonly
=
readonly
?:
chatRoom
.
readonly
,
...
@@ -402,14 +406,15 @@ class DatabaseManager(val context: Application,
...
@@ -402,14 +406,15 @@ class DatabaseManager(val context: Application,
groupMentions
=
groupMentions
?:
chatRoom
.
groupMentions
,
groupMentions
=
groupMentions
?:
chatRoom
.
groupMentions
,
updatedAt
=
updatedAt
?:
chatRoom
.
updatedAt
,
updatedAt
=
updatedAt
?:
chatRoom
.
updatedAt
,
timestamp
=
timestamp
?:
chatRoom
.
timestamp
,
timestamp
=
timestamp
?:
chatRoom
.
timestamp
,
lastSeen
=
lastSeen
?:
chatRoom
.
lastSeen
lastSeen
=
lastSeen
?:
chatRoom
.
lastSeen
,
muted
=
chatRoom
.
muted
)
)
}
}
}
}
}
}
private
suspend
fun
insertChatRoom
(
data
:
BaseRoom
):
ChatRoomEntity
?
{
private
suspend
fun
insertChatRoom
(
data
:
BaseRoom
):
ChatRoomEntity
?
{
return
when
(
data
)
{
return
when
(
data
)
{
is
Room
->
insertRoom
(
data
)
is
Room
->
insertRoom
(
data
)
is
Subscription
->
insertSubscription
(
data
)
is
Subscription
->
insertSubscription
(
data
)
else
->
null
else
->
null
...
@@ -451,7 +456,8 @@ class DatabaseManager(val context: Application,
...
@@ -451,7 +456,8 @@ class DatabaseManager(val context: Application,
id
=
room
.
id
,
id
=
room
.
id
,
subscriptionId
=
subscription
.
id
,
subscriptionId
=
subscription
.
id
,
type
=
room
.
type
.
toString
(),
type
=
room
.
type
.
toString
(),
name
=
room
.
name
?:
subscription
.
name
?:
throw
NullPointerException
(),
// this should be filtered on the SDK
name
=
room
.
name
?:
subscription
.
name
?:
throw
NullPointerException
(),
// this should be filtered on the SDK
fullname
=
subscription
.
fullName
?:
room
.
fullName
,
fullname
=
subscription
.
fullName
?:
room
.
fullName
,
userId
=
userId
,
userId
=
userId
,
ownerId
=
room
.
user
?.
id
,
ownerId
=
room
.
user
?.
id
,
...
@@ -506,7 +512,8 @@ class DatabaseManager(val context: Application,
...
@@ -506,7 +512,8 @@ class DatabaseManager(val context: Application,
lastMessageText
=
mapLastMessageText
(
lastMessage
),
lastMessageText
=
mapLastMessageText
(
lastMessage
),
lastMessageUserId
=
lastMessage
?.
sender
?.
id
,
lastMessageUserId
=
lastMessage
?.
sender
?.
id
,
lastMessageTimestamp
=
lastMessage
?.
timestamp
,
lastMessageTimestamp
=
lastMessage
?.
timestamp
,
broadcast
=
broadcast
broadcast
=
broadcast
,
muted
=
room
.
muted
)
)
}
}
}
}
...
@@ -535,9 +542,11 @@ class DatabaseManager(val context: Application,
...
@@ -535,9 +542,11 @@ class DatabaseManager(val context: Application,
}
}
}
}
private
fun
findUser
(
userId
:
String
):
String
?
=
userDao
().
findUser
(
userId
)
private
suspend
fun
findUser
(
userId
:
String
):
String
?
=
retryDB
(
"findUser($userId)"
)
{
userDao
().
findUser
(
userId
)
}
private
fun
doOperation
(
operation
:
Operation
)
{
private
suspend
fun
doOperation
(
operation
:
Operation
)
{
retryDB
(
description
=
"doOperation($operation)"
)
{
when
(
operation
)
{
when
(
operation
)
{
is
Operation
.
ClearStatus
->
userDao
().
clearStatus
()
is
Operation
.
ClearStatus
->
userDao
().
clearStatus
()
is
Operation
.
UpdateRooms
->
{
is
Operation
.
UpdateRooms
->
{
...
@@ -569,6 +578,7 @@ class DatabaseManager(val context: Application,
...
@@ -569,6 +578,7 @@ class DatabaseManager(val context: Application,
}
}
}.
exhaustive
}.
exhaustive
}
}
}
}
}
sealed
class
Operation
{
sealed
class
Operation
{
...
@@ -579,6 +589,7 @@ sealed class Operation {
...
@@ -579,6 +589,7 @@ sealed class Operation {
val
toUpdate
:
List
<
ChatRoomEntity
>,
val
toUpdate
:
List
<
ChatRoomEntity
>,
val
toRemove
:
List
<
String
>
val
toRemove
:
List
<
String
>
)
:
Operation
()
)
:
Operation
()
data class
InsertRooms
(
val
chatRooms
:
List
<
ChatRoomEntity
>)
:
Operation
()
data class
InsertRooms
(
val
chatRooms
:
List
<
ChatRoomEntity
>)
:
Operation
()
data class
CleanInsertRooms
(
val
chatRooms
:
List
<
ChatRoomEntity
>)
:
Operation
()
data class
CleanInsertRooms
(
val
chatRooms
:
List
<
ChatRoomEntity
>)
:
Operation
()
...
@@ -609,7 +620,7 @@ private fun String.databaseName(): String {
...
@@ -609,7 +620,7 @@ private fun String.databaseName(): String {
val
tmp
=
this
.
removePrefix
(
"https://"
)
val
tmp
=
this
.
removePrefix
(
"https://"
)
.
removePrefix
(
"http://"
)
.
removePrefix
(
"http://"
)
.
removeTrailingSlash
()
.
removeTrailingSlash
()
.
replace
(
"/"
,
"-"
)
.
replace
(
"/"
,
"-"
)
.
replace
(
"."
,
"_"
)
.
replace
(
"."
,
"_"
)
return
"$tmp.db"
return
"$tmp.db"
...
...
app/src/main/java/chat/rocket/android/db/RCDatabase.kt
View file @
ee16b416
...
@@ -2,6 +2,7 @@ package chat.rocket.android.db
...
@@ -2,6 +2,7 @@ package chat.rocket.android.db
import
androidx.room.Database
import
androidx.room.Database
import
androidx.room.RoomDatabase
import
androidx.room.RoomDatabase
import
androidx.room.TypeConverters
import
chat.rocket.android.db.model.AttachmentActionEntity
import
chat.rocket.android.db.model.AttachmentActionEntity
import
chat.rocket.android.db.model.AttachmentEntity
import
chat.rocket.android.db.model.AttachmentEntity
import
chat.rocket.android.db.model.AttachmentFieldEntity
import
chat.rocket.android.db.model.AttachmentFieldEntity
...
@@ -14,6 +15,7 @@ import chat.rocket.android.db.model.MessagesSync
...
@@ -14,6 +15,7 @@ import chat.rocket.android.db.model.MessagesSync
import
chat.rocket.android.db.model.ReactionEntity
import
chat.rocket.android.db.model.ReactionEntity
import
chat.rocket.android.db.model.UrlEntity
import
chat.rocket.android.db.model.UrlEntity
import
chat.rocket.android.db.model.UserEntity
import
chat.rocket.android.db.model.UserEntity
import
chat.rocket.android.emoji.internal.db.StringListConverter
@Database
(
@Database
(
entities
=
[
entities
=
[
...
@@ -23,9 +25,10 @@ import chat.rocket.android.db.model.UserEntity
...
@@ -23,9 +25,10 @@ import chat.rocket.android.db.model.UserEntity
AttachmentFieldEntity
::
class
,
AttachmentActionEntity
::
class
,
UrlEntity
::
class
,
AttachmentFieldEntity
::
class
,
AttachmentActionEntity
::
class
,
UrlEntity
::
class
,
ReactionEntity
::
class
,
MessagesSync
::
class
ReactionEntity
::
class
,
MessagesSync
::
class
],
],
version
=
1
0
,
version
=
1
2
,
exportSchema
=
true
exportSchema
=
true
)
)
@TypeConverters
(
StringListConverter
::
class
)
abstract
class
RCDatabase
:
RoomDatabase
()
{
abstract
class
RCDatabase
:
RoomDatabase
()
{
abstract
fun
userDao
():
UserDao
abstract
fun
userDao
():
UserDao
abstract
fun
chatRoomDao
():
ChatRoomDao
abstract
fun
chatRoomDao
():
ChatRoomDao
...
...
app/src/main/java/chat/rocket/android/db/model/ChatRoomEntity.kt
View file @
ee16b416
...
@@ -5,6 +5,8 @@ import androidx.room.Entity
...
@@ -5,6 +5,8 @@ import androidx.room.Entity
import
androidx.room.ForeignKey
import
androidx.room.ForeignKey
import
androidx.room.Index
import
androidx.room.Index
import
androidx.room.PrimaryKey
import
androidx.room.PrimaryKey
import
androidx.room.TypeConverters
import
chat.rocket.android.emoji.internal.db.StringListConverter
@Entity
(
tableName
=
"chatrooms"
,
@Entity
(
tableName
=
"chatrooms"
,
indices
=
[
indices
=
[
...
@@ -20,6 +22,7 @@ import androidx.room.PrimaryKey
...
@@ -20,6 +22,7 @@ import androidx.room.PrimaryKey
ForeignKey
(
entity
=
UserEntity
::
class
,
parentColumns
=
[
"id"
],
childColumns
=
[
"lastMessageUserId"
])
ForeignKey
(
entity
=
UserEntity
::
class
,
parentColumns
=
[
"id"
],
childColumns
=
[
"lastMessageUserId"
])
]
]
)
)
@TypeConverters
(
StringListConverter
::
class
)
data class
ChatRoomEntity
(
data class
ChatRoomEntity
(
@PrimaryKey
var
id
:
String
,
@PrimaryKey
var
id
:
String
,
var
subscriptionId
:
String
,
var
subscriptionId
:
String
,
...
@@ -42,7 +45,8 @@ data class ChatRoomEntity(
...
@@ -42,7 +45,8 @@ data class ChatRoomEntity(
var
lastMessageText
:
String
?
=
null
,
var
lastMessageText
:
String
?
=
null
,
var
lastMessageUserId
:
String
?
=
null
,
var
lastMessageUserId
:
String
?
=
null
,
var
lastMessageTimestamp
:
Long
?
=
null
,
var
lastMessageTimestamp
:
Long
?
=
null
,
var
broadcast
:
Boolean
?
=
false
var
broadcast
:
Boolean
?
=
false
,
var
muted
:
List
<
String
>?
=
null
)
)
data class
ChatRoom
(
data class
ChatRoom
(
...
...
app/src/main/java/chat/rocket/android/favoritemessages/presentation/FavoriteMessagesPresenter.kt
View file @
ee16b416
...
@@ -5,6 +5,7 @@ import chat.rocket.android.core.lifecycle.CancelStrategy
...
@@ -5,6 +5,7 @@ import chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
import
chat.rocket.common.util.ifNull
...
...
app/src/main/java/chat/rocket/android/files/presentation/FilesPresenter.kt
View file @
ee16b416
...
@@ -7,6 +7,7 @@ import chat.rocket.android.files.uimodel.FileUiModel
...
@@ -7,6 +7,7 @@ import chat.rocket.android.files.uimodel.FileUiModel
import
chat.rocket.android.files.uimodel.FileUiModelMapper
import
chat.rocket.android.files.uimodel.FileUiModelMapper
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
import
chat.rocket.common.util.ifNull
...
...
app/src/main/java/chat/rocket/android/members/presentation/MembersPresenter.kt
View file @
ee16b416
...
@@ -6,6 +6,7 @@ import chat.rocket.android.members.uimodel.MemberUiModel
...
@@ -6,6 +6,7 @@ import chat.rocket.android.members.uimodel.MemberUiModel
import
chat.rocket.android.members.uimodel.MemberUiModelMapper
import
chat.rocket.android.members.uimodel.MemberUiModelMapper
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
import
chat.rocket.common.util.ifNull
...
...
app/src/main/java/chat/rocket/android/pinnedmessages/presentation/PinnedMessagesPresenter.kt
View file @
ee16b416
...
@@ -5,6 +5,7 @@ import chat.rocket.android.core.lifecycle.CancelStrategy
...
@@ -5,6 +5,7 @@ import chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
import
chat.rocket.common.util.ifNull
...
...
app/src/main/java/chat/rocket/android/push/PushManager.kt
View file @
ee16b416
...
@@ -296,11 +296,8 @@ class PushManager @Inject constructor(
...
@@ -296,11 +296,8 @@ class PushManager @Inject constructor(
}
}
private
fun
getContentIntent
(
context
:
Context
,
notificationId
:
Int
,
pushMessage
:
PushMessage
,
grouped
:
Boolean
=
false
):
PendingIntent
{
private
fun
getContentIntent
(
context
:
Context
,
notificationId
:
Int
,
pushMessage
:
PushMessage
,
grouped
:
Boolean
=
false
):
PendingIntent
{
val
notificationIntent
=
context
.
changeServerIntent
(
pushMessage
.
info
.
host
,
chatRoomId
=
pushMessage
.
info
.
roomId
)
val
roomId
=
if
(!
grouped
)
pushMessage
.
info
.
roomId
else
null
// TODO - add support to go directly to the chatroom
val
notificationIntent
=
context
.
changeServerIntent
(
pushMessage
.
info
.
host
,
chatRoomId
=
roomId
)
/*if (!isGrouped) {
notificationIntent.putExtra(EXTRA_ROOM_ID, pushMessage.info.roomId)
}*/
return
PendingIntent
.
getActivity
(
context
,
random
.
nextInt
(),
notificationIntent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
)
return
PendingIntent
.
getActivity
(
context
,
random
.
nextInt
(),
notificationIntent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
)
}
}
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/ConnectionManager.kt
View file @
ee16b416
...
@@ -22,6 +22,7 @@ import chat.rocket.core.internal.realtime.unsubscribe
...
@@ -22,6 +22,7 @@ import chat.rocket.core.internal.realtime.unsubscribe
import
chat.rocket.core.internal.rest.chatRooms
import
chat.rocket.core.internal.rest.chatRooms
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Myself
import
chat.rocket.core.model.Myself
import
chat.rocket.core.model.Room
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.Job
import
kotlinx.coroutines.experimental.Job
import
kotlinx.coroutines.experimental.channels.Channel
import
kotlinx.coroutines.experimental.channels.Channel
...
@@ -45,6 +46,7 @@ class ConnectionManager(
...
@@ -45,6 +46,7 @@ class ConnectionManager(
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
roomsChannels
=
LinkedHashMap
<
String
,
Channel
<
Room
>>()
private
val
subscriptionIdMap
=
HashMap
<
String
,
String
>()
private
val
subscriptionIdMap
=
HashMap
<
String
,
String
>()
private
var
subscriptionId
:
String
?
=
null
private
var
subscriptionId
:
String
?
=
null
...
@@ -127,6 +129,18 @@ class ConnectionManager(
...
@@ -127,6 +129,18 @@ class ConnectionManager(
maxSize
=
10
)
{
batch
->
maxSize
=
10
)
{
batch
->
Timber
.
d
(
"processing Stream batch: ${batch.size} - $batch"
)
Timber
.
d
(
"processing Stream batch: ${batch.size} - $batch"
)
dbManager
.
processChatRoomsBatch
(
batch
)
dbManager
.
processChatRoomsBatch
(
batch
)
batch
.
forEach
{
//TODO - Do we need to handle Type.Removed and Type.Inserted here?
if
(
it
.
type
==
Type
.
Updated
)
{
if
(
it
.
data
is
Room
)
{
val
room
=
it
.
data
as
Room
roomsChannels
[
it
.
data
.
id
]
?.
let
{
channel
->
channel
.
offer
(
room
)
}
}
}
}
}
}
val
messagesActor
=
createBatchActor
<
Message
>(
messagesContext
,
parent
=
connectJob
,
val
messagesActor
=
createBatchActor
<
Message
>(
messagesContext
,
parent
=
connectJob
,
...
@@ -241,6 +255,14 @@ class ConnectionManager(
...
@@ -241,6 +255,14 @@ class ConnectionManager(
fun
removeUserDataChannel
(
channel
:
Channel
<
Myself
>)
=
userDataChannels
.
remove
(
channel
)
fun
removeUserDataChannel
(
channel
:
Channel
<
Myself
>)
=
userDataChannels
.
remove
(
channel
)
fun
addRoomChannel
(
roomId
:
String
,
channel
:
Channel
<
Room
>)
{
roomsChannels
[
roomId
]
=
channel
}
fun
removeRoomChannel
(
roomId
:
String
)
{
roomsChannels
.
remove
(
roomId
)
}
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/DatabaseMessageMapper.kt
View file @
ee16b416
...
@@ -7,6 +7,7 @@ import chat.rocket.android.db.model.FullMessage
...
@@ -7,6 +7,7 @@ import chat.rocket.android.db.model.FullMessage
import
chat.rocket.android.db.model.ReactionEntity
import
chat.rocket.android.db.model.ReactionEntity
import
chat.rocket.android.db.model.UrlEntity
import
chat.rocket.android.db.model.UrlEntity
import
chat.rocket.android.db.model.UserEntity
import
chat.rocket.android.db.model.UserEntity
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.model.SimpleRoom
import
chat.rocket.common.model.SimpleRoom
import
chat.rocket.common.model.SimpleUser
import
chat.rocket.common.model.SimpleUser
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Message
...
@@ -135,14 +136,18 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
...
@@ -135,14 +136,18 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
with
(
attachment
)
{
with
(
attachment
)
{
val
fields
=
if
(
hasFields
)
{
val
fields
=
if
(
hasFields
)
{
withContext
(
CommonPool
)
{
withContext
(
CommonPool
)
{
retryDB
(
"getAttachmentFields(${attachment._id})"
)
{
dbManager
.
messageDao
().
getAttachmentFields
(
attachment
.
_id
)
dbManager
.
messageDao
().
getAttachmentFields
(
attachment
.
_id
)
}
}.
map
{
Field
(
it
.
title
,
it
.
value
)
}
}.
map
{
Field
(
it
.
title
,
it
.
value
)
}
}
else
{
}
else
{
null
null
}
}
val
actions
=
if
(
hasActions
)
{
val
actions
=
if
(
hasActions
)
{
withContext
(
CommonPool
)
{
withContext
(
CommonPool
)
{
retryDB
(
"getAttachmentActions(${attachment._id})"
)
{
dbManager
.
messageDao
().
getAttachmentActions
(
attachment
.
_id
)
dbManager
.
messageDao
().
getAttachmentActions
(
attachment
.
_id
)
}
}.
mapNotNull
{
mapAction
(
it
)
}
}.
mapNotNull
{
mapAction
(
it
)
}
}
else
{
}
else
{
null
null
...
@@ -183,29 +188,6 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
...
@@ -183,29 +188,6 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
return
list
return
list
}
}
/*private suspend fun mapColorAttachmentWithFields(entity: AttachmentEntity): ColorAttachment {
val fields = withContext(CommonPool) {
dbManager.messageDao().getAttachmentFields(entity._id)
}.map { Field(it.title, it.value) }
return with(entity) {
ColorAttachment(
color = Color.Custom(color ?: DEFAULT_COLOR_STR),
text = text ?: "",
fallback = fallback,
fields = fields)
}
}
private suspend fun mapActionAttachment(attachment: AttachmentEntity): ActionsAttachment {
val actions = withContext(CommonPool) {
dbManager.messageDao().getAttachmentActions(attachment._id)
}.mapNotNull { mapAction(it) }
return with(attachment) {
// TODO - remove the default "vertical" value from here...
ActionsAttachment(title, actions, buttonAlignment ?: "vertical")
}
}*/
private
fun
mapAction
(
action
:
AttachmentActionEntity
):
Action
?
{
private
fun
mapAction
(
action
:
AttachmentActionEntity
):
Action
?
{
return
when
(
action
.
type
)
{
return
when
(
action
.
type
)
{
"button"
->
ButtonAction
(
action
.
type
,
action
.
text
,
action
.
url
,
action
.
isWebView
,
"button"
->
ButtonAction
(
action
.
type
,
action
.
text
,
action
.
url
,
action
.
isWebView
,
...
@@ -214,13 +196,4 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
...
@@ -214,13 +196,4 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
else
->
null
else
->
null
}
}
}
}
/*private suspend fun mapAuthorAttachment(attachment: AttachmentEntity): AuthorAttachment {
val fields = withContext(CommonPool) {
dbManager.messageDao().getAttachmentFields(attachment._id)
}.map { Field(it.title, it.value) }
return with(attachment) {
AuthorAttachment(authorLink!!, authorIcon, authorName, fields)
}
}*/
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/infraestructure/DatabaseMessagesRepository.kt
View file @
ee16b416
...
@@ -4,6 +4,7 @@ import chat.rocket.android.db.DatabaseManager
...
@@ -4,6 +4,7 @@ import chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.db.Operation
import
chat.rocket.android.db.Operation
import
chat.rocket.android.db.model.MessagesSync
import
chat.rocket.android.db.model.MessagesSync
import
chat.rocket.android.server.domain.MessagesRepository
import
chat.rocket.android.server.domain.MessagesRepository
import
chat.rocket.android.util.retryDB
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Message
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.withContext
import
kotlinx.coroutines.experimental.withContext
...
@@ -14,26 +15,32 @@ class DatabaseMessagesRepository(
...
@@ -14,26 +15,32 @@ class DatabaseMessagesRepository(
)
:
MessagesRepository
{
)
:
MessagesRepository
{
override
suspend
fun
getById
(
id
:
String
):
Message
?
=
withContext
(
CommonPool
)
{
override
suspend
fun
getById
(
id
:
String
):
Message
?
=
withContext
(
CommonPool
)
{
retryDB
(
"getMessageById($id)"
)
{
dbManager
.
messageDao
().
getMessageById
(
id
)
?.
let
{
message
->
mapper
.
map
(
message
)
}
dbManager
.
messageDao
().
getMessageById
(
id
)
?.
let
{
message
->
mapper
.
map
(
message
)
}
}
}
}
override
suspend
fun
getByRoomId
(
roomId
:
String
):
List
<
Message
>
=
withContext
(
CommonPool
)
{
override
suspend
fun
getByRoomId
(
roomId
:
String
):
List
<
Message
>
=
withContext
(
CommonPool
)
{
// FIXME - investigate how to avoid this distinctBy here, since DAO is returning a lot of
// FIXME - investigate how to avoid this distinctBy here, since DAO is returning a lot of
// duplicate rows (something related to our JOINS and relations on Room)
// duplicate rows (something related to our JOINS and relations on Room)
retryDB
(
"getMessagesByRoomId($roomId)"
)
{
dbManager
.
messageDao
().
getMessagesByRoomId
(
roomId
)
dbManager
.
messageDao
().
getMessagesByRoomId
(
roomId
)
.
distinctBy
{
it
.
message
.
message
.
id
}
.
distinctBy
{
it
.
message
.
message
.
id
}
.
let
{
messages
->
.
let
{
messages
->
mapper
.
map
(
messages
)
mapper
.
map
(
messages
)
}
}
}
}
}
override
suspend
fun
getRecentMessages
(
roomId
:
String
,
count
:
Long
):
List
<
Message
>
=
withContext
(
CommonPool
)
{
override
suspend
fun
getRecentMessages
(
roomId
:
String
,
count
:
Long
):
List
<
Message
>
=
withContext
(
CommonPool
)
{
retryDB
(
"getRecentMessagesByRoomId($roomId, $count)"
)
{
dbManager
.
messageDao
().
getRecentMessagesByRoomId
(
roomId
,
count
)
dbManager
.
messageDao
().
getRecentMessagesByRoomId
(
roomId
,
count
)
.
distinctBy
{
it
.
message
.
message
.
id
}
.
distinctBy
{
it
.
message
.
message
.
id
}
.
let
{
messages
->
.
let
{
messages
->
mapper
.
map
(
messages
)
mapper
.
map
(
messages
)
}
}
}
}
}
override
suspend
fun
save
(
message
:
Message
)
{
override
suspend
fun
save
(
message
:
Message
)
{
dbManager
.
processMessagesBatch
(
listOf
(
message
)).
join
()
dbManager
.
processMessagesBatch
(
listOf
(
message
)).
join
()
...
@@ -45,27 +52,33 @@ class DatabaseMessagesRepository(
...
@@ -45,27 +52,33 @@ class DatabaseMessagesRepository(
override
suspend
fun
removeById
(
id
:
String
)
{
override
suspend
fun
removeById
(
id
:
String
)
{
withContext
(
CommonPool
)
{
withContext
(
CommonPool
)
{
dbManager
.
messageDao
().
delete
(
id
)
retryDB
(
"delete($id)"
)
{
dbManager
.
messageDao
().
delete
(
id
)
}
}
}
}
}
override
suspend
fun
removeByRoomId
(
roomId
:
String
)
{
override
suspend
fun
removeByRoomId
(
roomId
:
String
)
{
withContext
(
CommonPool
)
{
withContext
(
CommonPool
)
{
retryDB
(
"deleteByRoomId($roomId)"
)
{
dbManager
.
messageDao
().
deleteByRoomId
(
roomId
)
dbManager
.
messageDao
().
deleteByRoomId
(
roomId
)
}
}
}
}
}
override
suspend
fun
getAllUnsent
():
List
<
Message
>
=
withContext
(
CommonPool
)
{
override
suspend
fun
getAllUnsent
():
List
<
Message
>
=
withContext
(
CommonPool
)
{
retryDB
(
"getUnsentMessages"
)
{
dbManager
.
messageDao
().
getUnsentMessages
()
dbManager
.
messageDao
().
getUnsentMessages
()
.
distinctBy
{
it
.
message
.
message
.
id
}
.
distinctBy
{
it
.
message
.
message
.
id
}
.
let
{
mapper
.
map
(
it
)
}
.
let
{
mapper
.
map
(
it
)
}
}
}
}
override
suspend
fun
saveLastSyncDate
(
roomId
:
String
,
timeMillis
:
Long
)
{
override
suspend
fun
saveLastSyncDate
(
roomId
:
String
,
timeMillis
:
Long
)
{
dbManager
.
sendOperation
(
Operation
.
SaveLastSync
(
MessagesSync
(
roomId
,
timeMillis
)))
dbManager
.
sendOperation
(
Operation
.
SaveLastSync
(
MessagesSync
(
roomId
,
timeMillis
)))
}
}
override
suspend
fun
getLastSyncDate
(
roomId
:
String
):
Long
?
=
withContext
(
CommonPool
)
{
override
suspend
fun
getLastSyncDate
(
roomId
:
String
):
Long
?
=
withContext
(
CommonPool
)
{
retryDB
(
"getLastSync($roomId)"
)
{
dbManager
.
messageDao
().
getLastSync
(
roomId
)
?.
let
{
it
.
timestamp
}
dbManager
.
messageDao
().
getLastSync
(
roomId
)
?.
let
{
it
.
timestamp
}
}
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/settings/password/presentation/PasswordPresenter.kt
View file @
ee16b416
package
chat.rocket.android.settings.password.presentation
package
chat.rocket.android.settings.password.presentation
import
chat.rocket.android.analytics.AnalyticsManager
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
...
@@ -14,6 +15,7 @@ import javax.inject.Inject
...
@@ -14,6 +15,7 @@ import javax.inject.Inject
class
PasswordPresenter
@Inject
constructor
(
class
PasswordPresenter
@Inject
constructor
(
private
val
view
:
PasswordView
,
private
val
view
:
PasswordView
,
private
val
strategy
:
CancelStrategy
,
private
val
strategy
:
CancelStrategy
,
private
val
analyticsManager
:
AnalyticsManager
,
serverInteractor
:
GetCurrentServerInteractor
,
serverInteractor
:
GetCurrentServerInteractor
,
factory
:
RocketChatClientFactory
factory
:
RocketChatClientFactory
)
{
)
{
...
@@ -30,10 +32,12 @@ class PasswordPresenter @Inject constructor(
...
@@ -30,10 +32,12 @@ class PasswordPresenter @Inject constructor(
client
.
updateProfile
(
me
.
id
,
null
,
null
,
password
,
null
)
client
.
updateProfile
(
me
.
id
,
null
,
null
,
password
,
null
)
}
}
analyticsManager
.
logResetPassword
(
true
)
view
.
showPasswordSuccessfullyUpdatedMessage
()
view
.
showPasswordSuccessfullyUpdatedMessage
()
view
.
hideLoading
()
}
catch
(
exception
:
RocketChatException
)
{
}
catch
(
exception
:
RocketChatException
)
{
analyticsManager
.
logResetPassword
(
false
)
view
.
showPasswordFailsUpdateMessage
(
exception
.
message
)
view
.
showPasswordFailsUpdateMessage
(
exception
.
message
)
}
finally
{
view
.
hideLoading
()
view
.
hideLoading
()
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/settings/ui/SettingsFragment.kt
View file @
ee16b416
...
@@ -8,6 +8,7 @@ import android.view.View
...
@@ -8,6 +8,7 @@ import android.view.View
import
android.view.ViewGroup
import
android.view.ViewGroup
import
android.widget.AdapterView
import
android.widget.AdapterView
import
androidx.appcompat.app.AppCompatActivity
import
androidx.appcompat.app.AppCompatActivity
import
androidx.core.net.toUri
import
androidx.fragment.app.Fragment
import
androidx.fragment.app.Fragment
import
chat.rocket.android.R
import
chat.rocket.android.R
import
chat.rocket.android.about.ui.AboutFragment
import
chat.rocket.android.about.ui.AboutFragment
...
@@ -72,25 +73,35 @@ class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListen
...
@@ -72,25 +73,35 @@ class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListen
resources
.
getStringArray
(
R
.
array
.
settings_actions
)[
1
]
->
resources
.
getStringArray
(
R
.
array
.
settings_actions
)[
1
]
->
activity
?.
startActivity
(
Intent
(
activity
,
PasswordActivity
::
class
.
java
))
activity
?.
startActivity
(
Intent
(
activity
,
PasswordActivity
::
class
.
java
))
resources
.
getStringArray
(
R
.
array
.
settings_actions
)[
2
]
->
{
resources
.
getStringArray
(
R
.
array
.
settings_actions
)[
2
]
->
shareApp
()
(
activity
as
AppCompatActivity
).
addFragmentBackStack
(
TAG_ABOUT_FRAGMENT
,
resources
.
getStringArray
(
R
.
array
.
settings_actions
)[
3
]
->
showAppOnStore
()
R
.
id
.
fragment_container
)
{
AboutFragment
.
newInstance
()
}
}
resources
.
getStringArray
(
R
.
array
.
settings_actions
)[
3
]
->
shareApp
()
resources
.
getStringArray
(
R
.
array
.
settings_actions
)[
4
]
->
contactSupport
()
resources
.
getStringArray
(
R
.
array
.
settings_actions
)[
4
]
->
activity
?.
startActivity
(
resources
.
getStringArray
(
R
.
array
.
settings_actions
)[
5
]
->
activity
?.
startActivity
(
context
?.
webViewIntent
(
context
?.
webViewIntent
(
getString
(
R
.
string
.
license_url
),
getString
(
R
.
string
.
license_url
),
getString
(
R
.
string
.
title_licence
)
getString
(
R
.
string
.
title_licence
)
)
)
)
)
resources
.
getStringArray
(
R
.
array
.
settings_actions
)[
5
]
->
contactSupport
()
resources
.
getStringArray
(
R
.
array
.
settings_actions
)[
6
]
->
{
(
activity
as
AppCompatActivity
).
addFragmentBackStack
(
TAG_ABOUT_FRAGMENT
,
R
.
id
.
fragment_container
)
{
AboutFragment
.
newInstance
()
}
}
}
}
private
fun
showAppOnStore
()
{
try
{
startActivity
(
Intent
(
Intent
.
ACTION_VIEW
,
getString
(
R
.
string
.
market_link
).
toUri
()))
}
catch
(
error
:
ActivityNotFoundException
)
{
startActivity
(
Intent
(
Intent
.
ACTION_VIEW
,
getString
(
R
.
string
.
play_store_link
).
toUri
()))
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/util/IO.kt
View file @
ee16b416
package
chat.rocket.android.util
package
chat.rocket.android.util
import
android.database.sqlite.SQLiteDatabaseLockedException
import
chat.rocket.common.RocketChatNetworkErrorException
import
chat.rocket.common.RocketChatNetworkErrorException
import
kotlinx.coroutines.experimental.TimeoutCancellationException
import
kotlinx.coroutines.experimental.TimeoutCancellationException
import
kotlinx.coroutines.experimental.delay
import
kotlinx.coroutines.experimental.delay
...
@@ -8,6 +9,7 @@ import timber.log.Timber
...
@@ -8,6 +9,7 @@ import timber.log.Timber
import
kotlin.coroutines.experimental.coroutineContext
import
kotlin.coroutines.experimental.coroutineContext
const
val
DEFAULT_RETRY
=
3
const
val
DEFAULT_RETRY
=
3
private
const
val
DEFAULT_DB_RETRY
=
5
suspend
fun
<
T
>
retryIO
(
suspend
fun
<
T
>
retryIO
(
description
:
String
=
"<missing description>"
,
description
:
String
=
"<missing description>"
,
...
@@ -35,3 +37,30 @@ suspend fun <T> retryIO(
...
@@ -35,3 +37,30 @@ suspend fun <T> retryIO(
if
(!
coroutineContext
.
isActive
)
throw
TimeoutCancellationException
(
"job canceled"
)
if
(!
coroutineContext
.
isActive
)
throw
TimeoutCancellationException
(
"job canceled"
)
return
block
()
// last attempt
return
block
()
// last attempt
}
}
suspend
fun
<
T
>
retryDB
(
description
:
String
=
"<missing description>"
,
times
:
Int
=
DEFAULT_DB_RETRY
,
initialDelay
:
Long
=
100
,
// 0.1 second
maxDelay
:
Long
=
500
,
// 0.5 second
factor
:
Double
=
1.2
,
block
:
suspend
()
->
T
):
T
{
var
currentDelay
=
initialDelay
repeat
(
times
-
1
)
{
currentTry
->
if
(!
coroutineContext
.
isActive
)
throw
TimeoutCancellationException
(
"job canceled"
)
try
{
return
block
()
}
catch
(
e
:
SQLiteDatabaseLockedException
)
{
Timber
.
d
(
e
,
"failed call($currentTry): $description"
)
e
.
printStackTrace
()
}
if
(!
coroutineContext
.
isActive
)
throw
TimeoutCancellationException
(
"job canceled"
)
delay
(
currentDelay
)
currentDelay
=
(
currentDelay
*
factor
).
toLong
().
coerceAtMost
(
maxDelay
)
}
if
(!
coroutineContext
.
isActive
)
throw
TimeoutCancellationException
(
"job canceled"
)
return
block
()
// last attempt
}
\ No newline at end of file
app/src/main/res/layout/emoji_image_row_item.xml
0 → 100644
View file @
ee16b416
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"48dp"
android:layout_height=
"48dp"
android:layout_gravity=
"center"
>
<ImageView
android:id=
"@+id/emoji_image_view"
android:layout_width=
"32dp"
android:layout_height=
"32dp"
android:layout_gravity=
"center"
tools:src=
"@tools:sample/avatars"
/>
</FrameLayout>
app/src/main/res/layout/emoji_row_item.xml
0 → 100644
View file @
ee16b416
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/emoji_view"
android:layout_width=
"48dp"
android:layout_height=
"48dp"
android:foreground=
"?selectableItemBackground"
android:layout_gravity=
"center"
android:gravity=
"center"
android:textColor=
"#000000"
android:textSize=
"24sp"
tools:text=
"😀"
/>
app/src/main/res/layout/reaction_praises_list_item.xml
0 → 100644
View file @
ee16b416
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"@color/colorWhite"
android:padding=
"16dp"
>
<ViewFlipper
android:id=
"@+id/view_flipper"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:foregroundGravity=
"center"
app:layout_constraintTop_toTopOf=
"parent"
>
<include
layout=
"@layout/emoji_row_item"
/>
<include
layout=
"@layout/emoji_image_row_item"
/>
</ViewFlipper>
<TextView
android:id=
"@+id/text_view_usernames"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:fontFamily=
"sans-serif-light"
android:textColor=
"@color/darkGray"
android:textSize=
"14sp"
app:layout_constraintBottom_toBottomOf=
"@+id/view_flipper"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toEndOf=
"@+id/view_flipper"
app:layout_constraintTop_toTopOf=
"@+id/view_flipper"
tools:text=
"Ann reacted with :grin:"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
app/src/main/res/values-de/strings.xml
View file @
ee16b416
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
<string
name=
"title_settings"
>
Einstellungen
</string>
<string
name=
"title_settings"
>
Einstellungen
</string>
<string
name=
"title_preferences"
>
Preferences
</string>
<!-- TODO Add translation -->
<string
name=
"title_preferences"
>
Preferences
</string>
<!-- TODO Add translation -->
<string
name=
"title_change_password"
>
Ändere Passwort
</string>
<string
name=
"title_change_password"
>
Ändere Passwort
</string>
<string
name=
"title_rate_us"
>
Bewerten Sie uns
</string>
<string
name=
"title_admin_panel"
>
Admin panel
</string>
<!-- TODO Add translation -->
<string
name=
"title_admin_panel"
>
Admin panel
</string>
<!-- TODO Add translation -->
<string
name=
"title_password"
>
Ändere Passwort
</string>
<string
name=
"title_password"
>
Ändere Passwort
</string>
<string
name=
"title_update_profile"
>
Update Profil
</string>
<string
name=
"title_update_profile"
>
Update Profil
</string>
...
@@ -58,11 +59,12 @@
...
@@ -58,11 +59,12 @@
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
<item
name=
"item_preferences"
>
Preferences
</item>
<!-- TODO Add translation -->
<item
name=
"item_preferences"
>
Preferences
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
Ändere Passwort
</item>
<item
name=
"item_password"
>
Change password
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
Über
</item>
<item
name=
"item_share_app"
>
Share app
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app"
>
App teilen
</item>
<item
name=
"item_rate_us"
>
Rate us
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_about"
>
About
</item>
<!-- TODO Add translation -->
</string-array>
</string-array>
<!-- Regular information messages -->
<!-- Regular information messages -->
...
@@ -151,6 +153,13 @@
...
@@ -151,6 +153,13 @@
<string
name=
"msg_continue_with_wordpress"
>
Continue with
<b>
WordPress
</b></string>
<!-- TODO Add translation -->
<string
name=
"msg_continue_with_wordpress"
>
Continue with
<b>
WordPress
</b></string>
<!-- TODO Add translation -->
<string
name=
"msg_two_factor_authentication"
>
Two-factor Authentication
</string>
<!-- TODO Add translation -->
<string
name=
"msg_two_factor_authentication"
>
Two-factor Authentication
</string>
<!-- TODO Add translation -->
<string
name=
"msg__your_2fa_code"
>
What’s your 2FA code?
</string>
<!-- TODO Add translation -->
<string
name=
"msg__your_2fa_code"
>
What’s your 2FA code?
</string>
<!-- TODO Add translation -->
<!-- TODO - Add proper translation -->
<string
name=
"msg_muted_on_this_channel"
>
You are muted on this channel
</string>
<!-- TODO - Add proper translation -->
<plurals
name=
"msg_reacted_with_"
>
<item
quantity=
"one"
>
%1$s reacted with %2$s
</item>
<item
quantity=
"other"
>
%1$s reacted with %2$s
</item>
</plurals>
<!-- Create channel messages -->
<!-- Create channel messages -->
<string
name=
"msg_private_channel"
>
Privat
</string>
<string
name=
"msg_private_channel"
>
Privat
</string>
...
...
app/src/main/res/values-es/strings.xml
View file @
ee16b416
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
<string
name=
"title_settings"
>
Configuraciones
</string>
<string
name=
"title_settings"
>
Configuraciones
</string>
<string
name=
"title_preferences"
>
Preferences
</string>
<!-- TODO Add translation -->
<string
name=
"title_preferences"
>
Preferences
</string>
<!-- TODO Add translation -->
<string
name=
"title_change_password"
>
Cambia la contraseña
</string>
<string
name=
"title_change_password"
>
Cambia la contraseña
</string>
<string
name=
"title_rate_us"
>
Nos califica
</string>
<string
name=
"title_admin_panel"
>
Admin panel
</string>
<!-- TODO Add translation -->
<string
name=
"title_admin_panel"
>
Admin panel
</string>
<!-- TODO Add translation -->
<string
name=
"title_password"
>
Cambia la contraseña
</string>
<string
name=
"title_password"
>
Cambia la contraseña
</string>
<string
name=
"title_update_profile"
>
Actualización del perfil
</string>
<string
name=
"title_update_profile"
>
Actualización del perfil
</string>
...
@@ -57,11 +58,12 @@
...
@@ -57,11 +58,12 @@
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
<item
name=
"item_preferences"
>
Preferences
</item>
<!-- TODO Add translation -->
<item
name=
"item_preferences"
>
Preferences
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
Cambia la contraseña
</item>
<item
name=
"item_password"
>
Change password
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
Acerca de
</item>
<item
name=
"item_share_app"
>
Share app
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app"
>
Compartir aplicación
</item>
<item
name=
"item_rate_us"
>
Rate us
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_about"
>
About
</item>
<!-- TODO Add translation -->
</string-array>
</string-array>
<!-- Regular information messages -->
<!-- Regular information messages -->
...
@@ -168,6 +170,11 @@
...
@@ -168,6 +170,11 @@
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_muted_on_this_channel"
>
You are muted on this channel
</string>
<!-- TODO - Add proper translation -->
<plurals
name=
"msg_reacted_with_"
>
<item
quantity=
"one"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
<item
quantity=
"other"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
</plurals>
<!-- Preferences messages -->
<!-- Preferences messages -->
<string
name=
"msg_analytics_tracking"
>
Analytics tracking
</string>
<!-- TODO Add translation -->
<string
name=
"msg_analytics_tracking"
>
Analytics tracking
</string>
<!-- TODO Add translation -->
...
...
app/src/main/res/values-fr/strings.xml
View file @
ee16b416
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
<string
name=
"title_settings"
>
Paramètres
</string>
<string
name=
"title_settings"
>
Paramètres
</string>
<string
name=
"title_preferences"
>
Préférences
</string>
<string
name=
"title_preferences"
>
Préférences
</string>
<string
name=
"title_change_password"
>
Changer le mot de passe
</string>
<string
name=
"title_change_password"
>
Changer le mot de passe
</string>
<string
name=
"title_rate_us"
>
évaluez nous
</string>
<string
name=
"title_admin_panel"
>
Administration
</string>
<string
name=
"title_admin_panel"
>
Administration
</string>
<string
name=
"title_password"
>
Changer le mot de passe
</string>
<string
name=
"title_password"
>
Changer le mot de passe
</string>
<string
name=
"title_update_profile"
>
Mettre à jour le profil
</string>
<string
name=
"title_update_profile"
>
Mettre à jour le profil
</string>
...
@@ -57,12 +58,13 @@
...
@@ -57,12 +58,13 @@
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
<item
name=
"item_preferences"
>
Préférences
</item>
<item
name=
"item_preferences"
>
Preferences
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
Changer le mot de passe
</item>
<item
name=
"item_password"
>
Change password
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
À propos
</item>
<item
name=
"item_share_app"
>
Share app
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app"
>
Partager l\'application
</item>
<item
name=
"item_rate_us"
>
Rate us
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_about"
>
About
</item>
<!-- TODO Add translation -->
</string-array>
</string-array>
<!-- Regular information messages -->
<!-- Regular information messages -->
...
@@ -160,6 +162,11 @@
...
@@ -160,6 +162,11 @@
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_muted_on_this_channel"
>
You are muted on this channel
</string>
<!-- TODO - Add proper translation -->
<plurals
name=
"msg_reacted_with_"
>
<item
quantity=
"one"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
<item
quantity=
"other"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
</plurals>
<!-- Create channel messages -->
<!-- Create channel messages -->
<string
name=
"msg_private_channel"
>
Privé
</string>
<string
name=
"msg_private_channel"
>
Privé
</string>
...
...
app/src/main/res/values-hi-rIN/strings.xml
View file @
ee16b416
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
<string
name=
"title_settings"
>
सेटिंग्स
</string>
<string
name=
"title_settings"
>
सेटिंग्स
</string>
<string
name=
"title_preferences"
>
प्राथमिकताएँ
</string>
<string
name=
"title_preferences"
>
प्राथमिकताएँ
</string>
<string
name=
"title_change_password"
>
पासवर्ड बदलें
</string>
<string
name=
"title_change_password"
>
पासवर्ड बदलें
</string>
<string
name=
"title_rate_us"
>
हमें रेटिंग दें
</string>
<string
name=
"title_admin_panel"
>
एडमिन पैनल
</string>
<string
name=
"title_admin_panel"
>
एडमिन पैनल
</string>
<string
name=
"title_password"
>
पासवर्ड बदलें
</string>
<string
name=
"title_password"
>
पासवर्ड बदलें
</string>
<string
name=
"title_update_profile"
>
प्रोफ़ाइल अपडेट करें
</string>
<string
name=
"title_update_profile"
>
प्रोफ़ाइल अपडेट करें
</string>
...
@@ -57,12 +58,13 @@
...
@@ -57,12 +58,13 @@
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
<item
name=
"item_preferences"
>
प्राथमिकताएँ
</item>
<item
name=
"item_preferences"
>
Preferences
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
पासवर्ड बदलें
</item>
<item
name=
"item_password"
>
Change password
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
परिचय
</item>
<item
name=
"item_share_app"
>
Share app
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app"
>
ऐप शेयर करें
</item>
<item
name=
"item_rate_us"
>
Rate us
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_about"
>
About
</item>
<!-- TODO Add translation -->
</string-array>
</string-array>
<!-- Regular information messages -->
<!-- Regular information messages -->
...
@@ -174,6 +176,12 @@
...
@@ -174,6 +176,12 @@
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_muted_on_this_channel"
>
You are muted on this channel
</string>
<!-- TODO - Add proper translation -->
<plurals
name=
"msg_reacted_with_"
>
<item
quantity=
"one"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
<item
quantity=
"few"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
<item
quantity=
"many"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
</plurals>
<!-- Preferences messages -->
<!-- Preferences messages -->
<string
name=
"msg_analytics_tracking"
>
एनालिटिक्स ट्रैकिंग
</string>
<string
name=
"msg_analytics_tracking"
>
एनालिटिक्स ट्रैकिंग
</string>
...
...
app/src/main/res/values-it/strings.xml
0 → 100644
View file @
ee16b416
This diff is collapsed.
Click to expand it.
app/src/main/res/values-ja/strings.xml
View file @
ee16b416
...
@@ -18,12 +18,14 @@
...
@@ -18,12 +18,14 @@
<string
name=
"title_settings"
>
設定
</string>
<string
name=
"title_settings"
>
設定
</string>
<string
name=
"title_preferences"
>
環境設定
</string>
<string
name=
"title_preferences"
>
環境設定
</string>
<string
name=
"title_change_password"
>
パスワードの変更
</string>
<string
name=
"title_change_password"
>
パスワードの変更
</string>
<string
name=
"title_rate_us"
>
私たちを評価してください
</string>
<string
name=
"title_admin_panel"
>
管理パネル
</string>
<string
name=
"title_admin_panel"
>
管理パネル
</string>
<string
name=
"title_password"
>
パスワードの変更
</string>
<string
name=
"title_password"
>
パスワードの変更
</string>
<string
name=
"title_update_profile"
>
プロフィールの更新
</string>
<string
name=
"title_update_profile"
>
プロフィールの更新
</string>
<string
name=
"title_about"
>
About
</string>
<string
name=
"title_about"
>
About
</string>
<string
name=
"title_licence"
>
Licence
</string>
<!-- TODO Add translation -->
<string
name=
"title_licence"
>
Licence
</string>
<!-- TODO Add translation -->
<string
name=
"title_create_channel"
>
新しいチャネルを作成
</string>
<string
name=
"title_create_channel"
>
新しいチャネルを作成
</string>
<string
name=
"title_are_you_sure"
>
本気ですか?
</string>
<!-- Actions -->
<!-- Actions -->
<string
name=
"action_connect"
>
接続
</string>
<string
name=
"action_connect"
>
接続
</string>
...
@@ -54,16 +56,17 @@
...
@@ -54,16 +56,17 @@
<string
name=
"action_create_server"
>
新規サーバーを作成
</string>
<string
name=
"action_create_server"
>
新規サーバーを作成
</string>
<string
name=
"action_register"
>
登録
</string>
<string
name=
"action_register"
>
登録
</string>
<string
name=
"action_confirm"
>
確認
</string>
<string
name=
"action_confirm"
>
確認
</string>
<string
name=
"action_delete_account"
>
Delete account
</string>
<!-- TODO Add translation --
>
<string
name=
"action_delete_account"
>
アカウントを削除する
</string
>
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
<item
name=
"item_preferences"
>
環境設定
</item>
<item
name=
"item_preferences"
>
Preferences
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
パスワードの変更
</item>
<item
name=
"item_password"
>
Change password
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
アプリ情報
</item>
<item
name=
"item_share_app"
>
Share app
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app"
>
アプリを共有する
</item>
<item
name=
"item_rate_us"
>
Rate us
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_about"
>
About
</item>
<!-- TODO Add translation -->
</string-array>
</string-array>
<!-- Regular information messages -->
<!-- Regular information messages -->
...
@@ -155,10 +158,14 @@
...
@@ -155,10 +158,14 @@
<string
name=
"msg_continue_with_wordpress"
><b>
WordPress
</b>
でログイン
</string>
<string
name=
"msg_continue_with_wordpress"
><b>
WordPress
</b>
でログイン
</string>
<string
name=
"msg_two_factor_authentication"
>
二要素認証
</string>
<string
name=
"msg_two_factor_authentication"
>
二要素認証
</string>
<string
name=
"msg__your_2fa_code"
>
あなたの 2FA コードは何ですか?
</string>
<string
name=
"msg__your_2fa_code"
>
あなたの 2FA コードは何ですか?
</string>
<string
name=
"msg_view_more"
>
更に表示
</string>
<string
name=
"msg_view_more"
>
更に表示
</string>
<string
name=
"msg_view_less"
>
隠す
</string>
<string
name=
"msg_view_less"
>
隠す
</string>
<string
name=
"msg_muted_on_this_channel"
>
あなたはこのチャンネルでミュートされています
</string>
<!-- TODO - Add proper translation -->
<plurals
name=
"msg_reacted_with_"
>
<item
quantity=
"one"
>
%1$s reacted with %2$s
</item>
<item
quantity=
"other"
>
%1$s reacted with %2$s
</item>
</plurals>
<!-- Create channel messages -->
<!-- Create channel messages -->
<string
name=
"msg_private_channel"
>
プライベート
</string>
<string
name=
"msg_private_channel"
>
プライベート
</string>
...
@@ -213,7 +220,6 @@
...
@@ -213,7 +220,6 @@
<string
name=
"action_msg_share"
>
Share
</string>
<string
name=
"action_msg_share"
>
Share
</string>
<string
name=
"action_title_editing"
>
メッセージの編集
</string>
<string
name=
"action_title_editing"
>
メッセージの編集
</string>
<string
name=
"action_msg_add_reaction"
>
リアクションする
</string>
<string
name=
"action_msg_add_reaction"
>
リアクションする
</string>
<!-- TODO - Add proper translation -->
<string
name=
"action_msg_copy_permalink"
>
パーマリンクのコピー
</string>
<string
name=
"action_msg_copy_permalink"
>
パーマリンクのコピー
</string>
<!-- Permission messages -->
<!-- Permission messages -->
...
...
app/src/main/res/values-pt-rBR/strings.xml
View file @
ee16b416
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
<string
name=
"title_settings"
>
Configurações
</string>
<string
name=
"title_settings"
>
Configurações
</string>
<string
name=
"title_preferences"
>
Preferencias
</string>
<string
name=
"title_preferences"
>
Preferencias
</string>
<string
name=
"title_change_password"
>
Alterar senha
</string>
<string
name=
"title_change_password"
>
Alterar senha
</string>
<string
name=
"title_rate_us"
>
nos avalie
</string>
<string
name=
"title_admin_panel"
>
Painel administrativo
</string>
<string
name=
"title_admin_panel"
>
Painel administrativo
</string>
<string
name=
"title_password"
>
Alterar senha
</string>
<string
name=
"title_password"
>
Alterar senha
</string>
<string
name=
"title_update_profile"
>
Editar perfil
</string>
<string
name=
"title_update_profile"
>
Editar perfil
</string>
...
@@ -57,12 +58,13 @@
...
@@ -57,12 +58,13 @@
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
<item
name=
"item_preferences"
>
Prefer
e
ncias
</item>
<item
name=
"item_preferences"
>
Prefer
ê
ncias
</item>
<item
name=
"item_password"
>
Alterar senha
</item>
<item
name=
"item_password"
>
Alterar senha
</item>
<item
name=
"item_password"
>
Sobre
</item>
<item
name=
"item_share_app"
>
Compartilhar app
</item>
<item
name=
"item_share_app"
>
Compartilhe o aplicativo
</item>
<item
name=
"item_rate_us"
>
Classifique-nos
</item>
<item
name=
"item_share_app_licence"
>
Licença
</item>
<item
name=
"item_contact_us"
>
Contate-nos
</item>
<item
name=
"item_contact_us"
>
Contate-nos
</item>
<item
name=
"item_licence"
>
Licença
</item>
<item
name=
"item_about"
>
Sobre
</item>
</string-array>
</string-array>
<!-- Regular information messages -->
<!-- Regular information messages -->
...
@@ -161,6 +163,11 @@
...
@@ -161,6 +163,11 @@
<string
name=
"msg_permalink_copied"
>
Permalink copiado
</string>
<string
name=
"msg_permalink_copied"
>
Permalink copiado
</string>
<string
name=
"msg_send_email"
>
Enviar e-mail
</string>
<string
name=
"msg_send_email"
>
Enviar e-mail
</string>
<string
name=
"msg_android_app_support"
>
Suporte ao aplicativo Android
</string>
<string
name=
"msg_android_app_support"
>
Suporte ao aplicativo Android
</string>
<string
name=
"msg_muted_on_this_channel"
>
Você está silenciado neste canal
</string>
<plurals
name=
"msg_reacted_with_"
>
<item
quantity=
"one"
>
%1$s reagiu com %2$s
</item>
<item
quantity=
"other"
>
%1$s reagiram com %2$s
</item>
</plurals>
<!-- Create channel messages -->
<!-- Create channel messages -->
<string
name=
"msg_private_channel"
>
Privado
</string>
<string
name=
"msg_private_channel"
>
Privado
</string>
...
@@ -189,8 +196,8 @@
...
@@ -189,8 +196,8 @@
<string
name=
"message_welcome"
>
Bem-vindo, %s
</string>
<string
name=
"message_welcome"
>
Bem-vindo, %s
</string>
<string
name=
"message_removed"
>
Mensagem removida
</string>
<string
name=
"message_removed"
>
Mensagem removida
</string>
<string
name=
"message_pinned"
>
Pinou uma mensagem:
</string>
<string
name=
"message_pinned"
>
Pinou uma mensagem:
</string>
<string
name=
"message_muted"
>
Usuário %1$s
entrou no modo mu
do por %2$s
</string>
<string
name=
"message_muted"
>
Usuário %1$s
foi silencia
do por %2$s
</string>
<string
name=
"message_unmuted"
>
Usuário %1$s saiu do modo
mu
do por %2$s
</string>
<string
name=
"message_unmuted"
>
Usuário %1$s saiu do modo
silencia
do por %2$s
</string>
<string
name=
"message_role_add"
>
%1$s foi definido %2$s por %3$s
</string>
<string
name=
"message_role_add"
>
%1$s foi definido %2$s por %3$s
</string>
<string
name=
"message_role_removed"
>
%1$s não é mais %2$s por %3$s
</string>
<string
name=
"message_role_removed"
>
%1$s não é mais %2$s por %3$s
</string>
// TODO:Add proper translation.
// TODO:Add proper translation.
...
...
app/src/main/res/values-ru-rRU/strings.xml
View file @
ee16b416
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
<string
name=
"title_settings"
>
Настройки
</string>
<string
name=
"title_settings"
>
Настройки
</string>
<string
name=
"title_preferences"
>
Персональные
</string>
<string
name=
"title_preferences"
>
Персональные
</string>
<string
name=
"title_change_password"
>
Изменить пароль
</string>
<string
name=
"title_change_password"
>
Изменить пароль
</string>
<string
name=
"title_rate_us"
>
оцените нас
</string>
<string
name=
"title_admin_panel"
>
Панель админа
</string>
<string
name=
"title_admin_panel"
>
Панель админа
</string>
<string
name=
"title_password"
>
Изменить пароль
</string>
<string
name=
"title_password"
>
Изменить пароль
</string>
<string
name=
"title_update_profile"
>
Обновить профиль
</string>
<string
name=
"title_update_profile"
>
Обновить профиль
</string>
...
@@ -57,12 +58,13 @@
...
@@ -57,12 +58,13 @@
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
<item
name=
"item_preferences"
>
Персональные
</item>
<item
name=
"item_preferences"
>
Preferences
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
Изменить пароль
</item>
<item
name=
"item_password"
>
Change password
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
О программе
</item>
<item
name=
"item_share_app"
>
Share app
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app"
>
добавить приложение
</item>
<item
name=
"item_rate_us"
>
Rate us
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_about"
>
About
</item>
<!-- TODO Add translation -->
</string-array>
</string-array>
<!-- Regular information messages -->
<!-- Regular information messages -->
...
@@ -159,6 +161,12 @@
...
@@ -159,6 +161,12 @@
<string
name=
"msg_permalink_copied"
>
Ссылка скопирована
</string>
<string
name=
"msg_permalink_copied"
>
Ссылка скопирована
</string>
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_muted_on_this_channel"
>
You are muted on this channel
</string>
<!-- TODO - Add proper translation -->
<plurals
name=
"msg_reacted_with_"
>
<item
quantity=
"one"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
<item
quantity=
"few"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
<item
quantity=
"many"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
</plurals>
<!-- Create channel messages -->
<!-- Create channel messages -->
<string
name=
"msg_private_channel"
>
Приватный
</string>
<string
name=
"msg_private_channel"
>
Приватный
</string>
...
...
app/src/main/res/values-tr/strings.xml
View file @
ee16b416
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
<string
name=
"title_settings"
>
Ayarlar
</string>
<string
name=
"title_settings"
>
Ayarlar
</string>
<string
name=
"title_preferences"
>
Tercihler
</string>
<string
name=
"title_preferences"
>
Tercihler
</string>
<string
name=
"title_change_password"
>
Şifre Değişikliği
</string>
<string
name=
"title_change_password"
>
Şifre Değişikliği
</string>
<string
name=
"title_rate_us"
>
Bizi değerlendirin
</string>
<string
name=
"title_admin_panel"
>
Yönetici Paneli
</string>
<string
name=
"title_admin_panel"
>
Yönetici Paneli
</string>
<string
name=
"title_password"
>
Şifrenizi Değiştirin
</string>
<string
name=
"title_password"
>
Şifrenizi Değiştirin
</string>
<string
name=
"title_update_profile"
>
Profilinizi Düzenleyin
</string>
<string
name=
"title_update_profile"
>
Profilinizi Düzenleyin
</string>
...
@@ -57,12 +58,13 @@
...
@@ -57,12 +58,13 @@
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
<item
name=
"item_preferences"
>
Tercihler
</item>
<item
name=
"item_preferences"
>
Preferences
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
Şifre Değiştir
</item>
<item
name=
"item_password"
>
Change password
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
Hakkında
</item>
<item
name=
"item_share_app"
>
Share app
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app"
>
uygulamayı Paylaş
</item>
<item
name=
"item_rate_us"
>
Rate us
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_about"
>
About
</item>
<!-- TODO Add translation -->
</string-array>
</string-array>
<!-- Regular information messages -->
<!-- Regular information messages -->
...
@@ -175,7 +177,11 @@
...
@@ -175,7 +177,11 @@
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_muted_on_this_channel"
>
You are muted on this channel
</string>
<!-- TODO - Add proper translation -->
<plurals
name=
"msg_reacted_with_"
>
<item
quantity=
"one"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
<item
quantity=
"other"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
</plurals>
<!-- Preferences messages -->
<!-- Preferences messages -->
<string
name=
"msg_analytics_tracking"
>
İstatistik takibi
</string>
<string
name=
"msg_analytics_tracking"
>
İstatistik takibi
</string>
<string
name=
"msg_send_analytics_tracking"
>
Uygulamanın gelişmesine katkıda bulunmak için anonim istatistik bilgisi gönder
</string>
<string
name=
"msg_send_analytics_tracking"
>
Uygulamanın gelişmesine katkıda bulunmak için anonim istatistik bilgisi gönder
</string>
...
...
app/src/main/res/values-uk/strings.xml
View file @
ee16b416
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
<string
name=
"title_settings"
>
Налаштування
</string>
<string
name=
"title_settings"
>
Налаштування
</string>
<string
name=
"title_preferences"
>
Персональні
</string>
<string
name=
"title_preferences"
>
Персональні
</string>
<string
name=
"title_change_password"
>
Змінити пароль
</string>
<string
name=
"title_change_password"
>
Змінити пароль
</string>
<string
name=
"title_rate_us"
>
Оцініть нас
</string>
<string
name=
"title_admin_panel"
>
Панель адміністратора
</string>
<string
name=
"title_admin_panel"
>
Панель адміністратора
</string>
<string
name=
"title_password"
>
Змінити пароль
</string>
<string
name=
"title_password"
>
Змінити пароль
</string>
<string
name=
"title_update_profile"
>
Оновити профіль
</string>
<string
name=
"title_update_profile"
>
Оновити профіль
</string>
...
@@ -58,11 +59,12 @@
...
@@ -58,11 +59,12 @@
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
<item
name=
"item_preferences"
>
Preferences
</item>
<!-- TODO Add translation -->
<item
name=
"item_preferences"
>
Preferences
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
Change Password
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
Change password
</item>
<!-- TODO Add translation -->
<item
name=
"item_password"
>
About
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app"
>
Share app
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app"
>
поділитися прикладом
</item>
<item
name=
"item_rate_us"
>
Rate us
</item>
<!-- TODO Add translation -->
<item
name=
"item_share_app_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_contact_us"
>
Contact us
</item>
<!-- TODO Add translation -->
<item
name=
"item_licence"
>
Licence
</item>
<!-- TODO Add translation -->
<item
name=
"item_about"
>
About
</item>
<!-- TODO Add translation -->
</string-array>
</string-array>
<!-- Regular information messages -->
<!-- Regular information messages -->
...
@@ -158,6 +160,12 @@
...
@@ -158,6 +160,12 @@
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_send_email"
>
Send email
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<!-- TODO - Add proper translation -->
<string
name=
"msg_muted_on_this_channel"
>
You are muted on this channel
</string>
<!-- TODO - Add proper translation -->
<plurals
name=
"msg_reacted_with_"
>
<item
quantity=
"one"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
<item
quantity=
"few"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
<item
quantity=
"many"
>
%1$s reacted with %2$s
</item>
<!-- TODO - Add proper translation -->
</plurals>
<!-- Create channel messages -->
<!-- Create channel messages -->
<string
name=
"msg_private_channel"
>
Приватний
</string>
<string
name=
"msg_private_channel"
>
Приватний
</string>
...
...
app/src/main/res/values/defaults.xml
View file @
ee16b416
...
@@ -5,5 +5,6 @@
...
@@ -5,5 +5,6 @@
<string
name=
"community_server_url"
translatable=
"false"
>
open.rocket.chat
</string>
<string
name=
"community_server_url"
translatable=
"false"
>
open.rocket.chat
</string>
<string
name=
"create_server_url"
translatable=
"false"
>
cloud.rocket.chat/trial
</string>
<string
name=
"create_server_url"
translatable=
"false"
>
cloud.rocket.chat/trial
</string>
<string
name=
"play_store_link"
translatable=
"false"
>
https://play.google.com/store/apps/details?id=chat.rocket.android
</string>
<string
name=
"play_store_link"
translatable=
"false"
>
https://play.google.com/store/apps/details?id=chat.rocket.android
</string>
<string
name=
"market_link"
translatable=
"false"
>
market://details?id=chat.rocket.android
</string>
<string
name=
"license_url"
translatable=
"false"
>
https://github.com/RocketChat/Rocket.Chat.Android/blob/develop/LICENSE
</string>
<string
name=
"license_url"
translatable=
"false"
>
https://github.com/RocketChat/Rocket.Chat.Android/blob/develop/LICENSE
</string>
</resources>
</resources>
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
ee16b416
...
@@ -28,6 +28,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
...
@@ -28,6 +28,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string
name=
"title_settings"
>
Settings
</string>
<string
name=
"title_settings"
>
Settings
</string>
<string
name=
"title_preferences"
>
Preferences
</string>
<string
name=
"title_preferences"
>
Preferences
</string>
<string
name=
"title_change_password"
>
Change Password
</string>
<string
name=
"title_change_password"
>
Change Password
</string>
<string
name=
"title_rate_us"
>
Rate Us
</string>
<string
name=
"title_admin_panel"
>
Admin panel
</string>
<string
name=
"title_admin_panel"
>
Admin panel
</string>
<string
name=
"title_password"
>
Change Password
</string>
<string
name=
"title_password"
>
Change Password
</string>
<string
name=
"title_update_profile"
>
Update profile
</string>
<string
name=
"title_update_profile"
>
Update profile
</string>
...
@@ -70,11 +71,12 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
...
@@ -70,11 +71,12 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
<item
name=
"item_preferences"
>
Preferences
</item>
<item
name=
"item_preferences"
>
Preferences
</item>
<item
name=
"item_password"
>
Change Password
</item>
<item
name=
"item_password"
>
Change password
</item>
<item
name=
"item_password"
>
About
</item>
<item
name=
"item_share_app"
>
Share app
</item>
<item
name=
"item_share_app"
>
Share App
</item>
<item
name=
"item_rate_us"
>
Rate us
</item>
<item
name=
"item_share_app_licence"
>
Licence
</item>
<item
name=
"item_contact_us"
>
Contact us
</item>
<item
name=
"item_contact_us"
>
Contact us
</item>
<item
name=
"item_licence"
>
Licence
</item>
<item
name=
"item_about"
>
About
</item>
</string-array>
</string-array>
<!-- Regular information messages -->
<!-- Regular information messages -->
...
@@ -171,6 +173,10 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
...
@@ -171,6 +173,10 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<string
name=
"msg_permalink_copied"
>
Permalink copied
</string>
<string
name=
"msg_send_email"
>
Send email
</string>
<string
name=
"msg_send_email"
>
Send email
</string>
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<string
name=
"msg_android_app_support"
>
Android app support
</string>
<plurals
name=
"msg_reacted_with_"
>
<item
quantity=
"one"
>
%1$s reacted with %2$s
</item>
<item
quantity=
"other"
>
%1$s reacted with %2$s
</item>
</plurals>
<!-- Create channel messages -->
<!-- Create channel messages -->
<string
name=
"msg_private_channel"
>
Private
</string>
<string
name=
"msg_private_channel"
>
Private
</string>
...
@@ -188,6 +194,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
...
@@ -188,6 +194,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string
name=
"msg_delete_description"
>
Are you sure you want to delete this message
</string>
<string
name=
"msg_delete_description"
>
Are you sure you want to delete this message
</string>
<string
name=
"msg_view_more"
>
view more
</string>
<string
name=
"msg_view_more"
>
view more
</string>
<string
name=
"msg_view_less"
>
view less
</string>
<string
name=
"msg_view_less"
>
view less
</string>
<string
name=
"msg_muted_on_this_channel"
>
You are muted on this channel
</string>
<!-- Preferences messages -->
<!-- Preferences messages -->
<string
name=
"msg_analytics_tracking"
>
Analytics tracking
</string>
<string
name=
"msg_analytics_tracking"
>
Analytics tracking
</string>
...
...
app/src/play/java/chat/rocket/android/analytics/AnswersAnalytics.kt
View file @
ee16b416
...
@@ -67,4 +67,11 @@ class AnswersAnalytics : Analytics {
...
@@ -67,4 +67,11 @@ class AnswersAnalytics : Analytics {
)
)
override
fun
logOpenAdmin
()
=
Answers
.
getInstance
().
logCustom
(
CustomEvent
(
"open_admin"
))
override
fun
logOpenAdmin
()
=
Answers
.
getInstance
().
logCustom
(
CustomEvent
(
"open_admin"
))
override
fun
logResetPassword
(
resetPasswordSucceeded
:
Boolean
)
=
Answers
.
getInstance
()
.
logCustom
(
CustomEvent
(
"reset_password"
)
.
putCustomAttribute
(
"resetPasswordSucceeded"
,
resetPasswordSucceeded
.
toString
())
)
}
}
app/src/play/java/chat/rocket/android/analytics/GoogleAnalyticsForFirebase.kt
View file @
ee16b416
...
@@ -60,4 +60,9 @@ class GoogleAnalyticsForFirebase @Inject constructor(val context: Context) :
...
@@ -60,4 +60,9 @@ class GoogleAnalyticsForFirebase @Inject constructor(val context: Context) :
}
}
override
fun
logOpenAdmin
()
=
firebaseAnalytics
.
logEvent
(
"open_admin"
,
null
)
override
fun
logOpenAdmin
()
=
firebaseAnalytics
.
logEvent
(
"open_admin"
,
null
)
override
fun
logResetPassword
(
resetPasswordSucceeded
:
Boolean
)
=
firebaseAnalytics
.
logEvent
(
"reset_password"
,
Bundle
(
1
).
apply
{
putBoolean
(
"resetPasswordSucceeded"
,
resetPasswordSucceeded
)
})
}
}
app/src/play/java/chat/rocket/android/push/FirebaseMessagingService.kt
View file @
ee16b416
package
chat.rocket.android.push
package
chat.rocket.android.push
import
android.os.Bundle
import
androidx.core.os.bundleOf
import
androidx.core.os.bundleOf
import
androidx.work.Constraints
import
androidx.work.Constraints
import
androidx.work.NetworkType
import
androidx.work.NetworkType
...
@@ -23,9 +24,12 @@ class FirebaseMessagingService : FirebaseMessagingService() {
...
@@ -23,9 +24,12 @@ class FirebaseMessagingService : FirebaseMessagingService() {
}
}
override
fun
onMessageReceived
(
message
:
RemoteMessage
)
{
override
fun
onMessageReceived
(
message
:
RemoteMessage
)
{
// XXX - for now this is ok, if we start to do network calls, use a Worker instead
message
.
data
?.
let
{
data
->
message
.
data
?.
let
{
val
bundle
=
Bundle
()
pushManager
.
handle
(
bundleOf
(*(
it
.
map
{
Pair
(
it
.
key
,
it
.
value
)
}).
toTypedArray
()))
data
.
entries
.
forEach
{
entry
->
bundle
.
putString
(
entry
.
key
,
entry
.
value
)
}
pushManager
.
handle
(
bundle
)
}
}
}
}
...
...
emoji/src/main/java/chat/rocket/android/emoji/EmojiKeyboardPopup.kt
View file @
ee16b416
...
@@ -10,7 +10,6 @@ import android.view.View
...
@@ -10,7 +10,6 @@ import android.view.View
import
android.view.ViewGroup
import
android.view.ViewGroup
import
android.widget.EditText
import
android.widget.EditText
import
android.widget.ImageView
import
android.widget.ImageView
import
android.widget.TextView
import
androidx.annotation.ColorInt
import
androidx.annotation.ColorInt
import
androidx.appcompat.app.AlertDialog
import
androidx.appcompat.app.AlertDialog
import
androidx.appcompat.app.AppCompatActivity
import
androidx.appcompat.app.AppCompatActivity
...
@@ -22,6 +21,7 @@ import chat.rocket.android.emoji.internal.EmojiCategory
...
@@ -22,6 +21,7 @@ import chat.rocket.android.emoji.internal.EmojiCategory
import
chat.rocket.android.emoji.internal.EmojiPagerAdapter
import
chat.rocket.android.emoji.internal.EmojiPagerAdapter
import
chat.rocket.android.emoji.internal.PREF_EMOJI_SKIN_TONE
import
chat.rocket.android.emoji.internal.PREF_EMOJI_SKIN_TONE
import
com.google.android.material.tabs.TabLayout
import
com.google.android.material.tabs.TabLayout
import
kotlinx.android.synthetic.main.dialog_skin_tone_chooser.view.*
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.launch
import
kotlinx.coroutines.experimental.launch
...
@@ -77,59 +77,50 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
...
@@ -77,59 +77,50 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
}
}
private
fun
showSkinToneChooser
()
{
private
fun
showSkinToneChooser
()
{
val
view
=
LayoutInflater
.
from
(
context
).
inflate
(
R
.
layout
.
color_select_popup
,
null
)
val
view
=
LayoutInflater
.
from
(
context
).
inflate
(
R
.
layout
.
dialog_skin_tone_chooser
,
null
)
val
dialog
=
AlertDialog
.
Builder
(
context
,
R
.
style
.
Dialog
)
val
dialog
=
AlertDialog
.
Builder
(
context
,
R
.
style
.
Dialog
)
.
setView
(
view
)
.
setView
(
view
)
.
setTitle
(
context
.
getString
(
R
.
string
.
alert_title_default_skin_tone
))
.
setTitle
(
context
.
getString
(
R
.
string
.
alert_title_default_skin_tone
))
.
setCancelable
(
true
)
.
setCancelable
(
true
)
.
create
()
.
create
()
view
.
findViewById
<
TextView
>(
R
.
id
.
default_tone_text
).
also
{
with
(
view
)
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
image_view_default_tone
.
setOnClickListener
{
}.
setOnClickListener
{
dialog
.
dismiss
()
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
Default
)
changeSkinTone
(
Fitzpatrick
.
Default
)
}
}
view
.
findViewById
<
TextView
>(
R
.
id
.
light_tone_text
).
also
{
image_view_light_tone
.
setOnClickListener
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
}.
setOnClickListener
{
dialog
.
dismiss
()
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
LightTone
)
changeSkinTone
(
Fitzpatrick
.
LightTone
)
}
}
view
.
findViewById
<
TextView
>(
R
.
id
.
medium_light_text
).
also
{
image_view_medium_light
.
setOnClickListener
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
}.
setOnClickListener
{
dialog
.
dismiss
()
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
MediumLightTone
)
changeSkinTone
(
Fitzpatrick
.
MediumLightTone
)
}
}
view
.
findViewById
<
TextView
>(
R
.
id
.
medium_tone_text
).
also
{
image_view_medium_tone
.
setOnClickListener
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
}.
setOnClickListener
{
dialog
.
dismiss
()
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
MediumTone
)
changeSkinTone
(
Fitzpatrick
.
MediumTone
)
}
}
view
.
findViewById
<
TextView
>(
R
.
id
.
medium_dark_tone_text
).
also
{
image_view_medium_dark_tone
.
setOnClickListener
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
}.
setOnClickListener
{
dialog
.
dismiss
()
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
MediumDarkTone
)
changeSkinTone
(
Fitzpatrick
.
MediumDarkTone
)
}
}
view
.
findViewById
<
TextView
>(
R
.
id
.
dark_tone_text
).
also
{
image_view_dark_tone
.
setOnClickListener
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
}.
setOnClickListener
{
dialog
.
dismiss
()
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
DarkTone
)
changeSkinTone
(
Fitzpatrick
.
DarkTone
)
}
}
}
dialog
.
show
()
dialog
.
show
()
}
}
private
fun
changeSkinTone
(
tone
:
Fitzpatrick
)
{
private
fun
changeSkinTone
(
tone
:
Fitzpatrick
)
{
val
drawable
=
ContextCompat
.
getDrawable
(
context
,
R
.
drawable
.
color_change_circl
e
)
!!
val
drawable
=
ContextCompat
.
getDrawable
(
context
,
R
.
drawable
.
bg_skin_ton
e
)
!!
val
wrappedDrawable
=
DrawableCompat
.
wrap
(
drawable
)
val
wrappedDrawable
=
DrawableCompat
.
wrap
(
drawable
)
DrawableCompat
.
setTint
(
wrappedDrawable
,
getFitzpatrickColor
(
tone
))
DrawableCompat
.
setTint
(
wrappedDrawable
,
getFitzpatrickColor
(
tone
))
(
changeColorView
as
ImageView
).
setImageDrawable
(
wrappedDrawable
)
(
changeColorView
as
ImageView
).
setImageDrawable
(
wrappedDrawable
)
...
...
emoji/src/main/java/chat/rocket/android/emoji/EmojiReactionListener.kt
View file @
ee16b416
...
@@ -16,4 +16,14 @@ interface EmojiReactionListener {
...
@@ -16,4 +16,14 @@ interface EmojiReactionListener {
* @param emojiShortname The shortname of the emoji (:grin:, :smiley:, etc).
* @param emojiShortname The shortname of the emoji (:grin:, :smiley:, etc).
*/
*/
fun
onReactionTouched
(
messageId
:
String
,
emojiShortname
:
String
)
fun
onReactionTouched
(
messageId
:
String
,
emojiShortname
:
String
)
/**
* Callback when an added reaction is long-clicked.
*
* @param shortname The shortname of the emoji (:grin:, :smiley:, etc).
* @param isCustom Whether the reaction is custom or one of the defaults.
* @param url In case of a custom emoji, this is the url to find it. Can be null if not a custom.
* @param usernames The list of usernames of users who added the reaction.
*/
fun
onReactionLongClicked
(
shortname
:
String
,
isCustom
:
Boolean
,
url
:
String
?,
usernames
:
List
<
String
>)
}
}
emoji/src/main/res/drawable/
color_change_circl
e.xml
→
emoji/src/main/res/drawable/
bg_skin_ton
e.xml
View file @
ee16b416
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"oval"
>
android:shape=
"oval"
>
<solid
android:color=
"@color/tone_default"
/>
<solid
android:color=
"@color/tone_default"
/>
<size
<size
android:width=
"24dp"
android:width=
"24dp"
android:height=
"24dp"
/>
android:height=
"24dp"
/>
...
...
emoji/src/main/res/layout/
color_select_popup
.xml
→
emoji/src/main/res/layout/
dialog_skin_tone_chooser
.xml
View file @
ee16b416
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout
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"
android:layout_width=
"match_parent"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
>
android:layout_height=
"wrap_content"
>
<
Text
View
<
Image
View
android:id=
"@+id/
default_tone_text
"
android:id=
"@+id/
image_view_default_tone
"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"24dp"
android:layout_marginTop=
"16dp"
android:layout_marginTop=
"16dp"
android:text=
"👌"
android:layout_marginBottom=
"16dp"
android:textSize=
"32sp"
android:tint=
"@color/tone_default"
android:tint=
"@color/tone_default"
app:layout_constraintEnd_toStartOf=
"@+id/light_tone_text"
app:layout_constraintBottom_toTopOf=
"@+id/image_view_medium_tone"
app:layout_constraintEnd_toStartOf=
"@+id/image_view_light_tone"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintHorizontal_chainStyle=
"
packed
"
app:layout_constraintHorizontal_chainStyle=
"
spread_inside
"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:srcCompat=
"@drawable/
color_change_circl
e"
/>
app:srcCompat=
"@drawable/
bg_skin_ton
e"
/>
<
Text
View
<
Image
View
android:id=
"@+id/
light_tone_text
"
android:id=
"@+id/
image_view_light_tone
"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"24dp"
android:layout_marginTop=
"16dp"
android:layout_marginTop=
"16dp"
android:layout_marginEnd=
"24dp"
android:text=
"👌🏻"
android:textSize=
"32sp"
android:tint=
"@color/tone_light"
android:tint=
"@color/tone_light"
app:layout_constraintEnd_toStartOf=
"@+id/
medium_light_tex
t"
app:layout_constraintEnd_toStartOf=
"@+id/
image_view_medium_ligh
t"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintStart_toEndOf=
"@+id/
default_tone_text
"
app:layout_constraintStart_toEndOf=
"@+id/
image_view_default_tone
"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:srcCompat=
"@drawable/color_change_circle"
app:srcCompat=
"@drawable/bg_skin_tone"
/>
tools:text=
"👌"
/>
<
Text
View
<
Image
View
android:id=
"@+id/
medium_light_tex
t"
android:id=
"@+id/
image_view_medium_ligh
t"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"16dp"
android:layout_marginTop=
"16dp"
android:text=
"👌🏼"
android:layout_marginEnd=
"24dp"
android:textSize=
"32sp"
android:tint=
"@color/tone_medium_light"
android:tint=
"@color/tone_medium_light"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintStart_toEndOf=
"@+id/
light_tone_text
"
app:layout_constraintStart_toEndOf=
"@+id/
image_view_light_tone
"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:srcCompat=
"@drawable/color_change_circle"
app:srcCompat=
"@drawable/bg_skin_tone"
/>
tools:text=
"👌"
/>
<
Text
View
<
Image
View
android:id=
"@+id/
medium_tone_text
"
android:id=
"@+id/
image_view_medium_tone
"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"8dp"
android:layout_marginTop=
"8dp"
android:layout_marginBottom=
"16dp"
android:layout_marginBottom=
"16dp"
android:text=
"👌🏽"
android:textSize=
"32sp"
android:tint=
"@color/tone_medium"
android:tint=
"@color/tone_medium"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toStartOf=
"@+id/medium_dark_tone_text"
app:layout_constraintEnd_toStartOf=
"@+id/image_view_medium_dark_tone"
app:layout_constraintHorizontal_chainStyle=
"packed"
app:layout_constraintHorizontal_chainStyle=
"spread_inside"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintStart_toStartOf=
"@+id/image_view_default_tone"
app:layout_constraintTop_toBottomOf=
"@+id/default_tone_text"
app:layout_constraintTop_toBottomOf=
"@+id/image_view_default_tone"
app:srcCompat=
"@drawable/color_change_circle"
app:srcCompat=
"@drawable/bg_skin_tone"
/>
tools:text=
"👌"
/>
<
Text
View
<
Image
View
android:id=
"@+id/
medium_dark_tone_text
"
android:id=
"@+id/
image_view_medium_dark_tone
"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"24dp"
android:layout_marginTop=
"8dp"
android:layout_marginEnd=
"24dp"
android:layout_marginBottom=
"16dp"
android:text=
"👌🏾"
android:textSize=
"32sp"
android:tint=
"@color/tone_medium_dark"
android:tint=
"@color/tone_medium_dark"
app:layout_constraintBottom_toBottomOf=
"
parent
"
app:layout_constraintBottom_toBottomOf=
"
@+id/image_view_medium_tone
"
app:layout_constraintEnd_toStartOf=
"@+id/
dark_tone_text
"
app:layout_constraintEnd_toStartOf=
"@+id/
image_view_dark_tone
"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintStart_toEndOf=
"@+id/medium_tone_text"
app:layout_constraintStart_toEndOf=
"@+id/image_view_medium_tone"
app:layout_constraintTop_toBottomOf=
"@+id/light_tone_text"
app:layout_constraintTop_toTopOf=
"@+id/image_view_medium_tone"
app:srcCompat=
"@drawable/color_change_circle"
app:srcCompat=
"@drawable/bg_skin_tone"
/>
tools:text=
"👌"
/>
<
Text
View
<
Image
View
android:id=
"@+id/
dark_tone_text
"
android:id=
"@+id/
image_view_dark_tone
"
android:layout_width=
"wrap_content"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"8dp"
android:layout_marginBottom=
"16dp"
android:text=
"👌🏿"
android:textSize=
"32sp"
android:tint=
"@color/tone_dark"
android:tint=
"@color/tone_dark"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"@+id/image_view_medium_dark_tone"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintEnd_toEndOf=
"@+id/image_view_medium_light"
app:layout_constraintStart_toEndOf=
"@+id/medium_dark_tone_text"
app:layout_constraintStart_toEndOf=
"@+id/image_view_medium_dark_tone"
app:layout_constraintTop_toBottomOf=
"@+id/medium_light_text"
app:layout_constraintTop_toTopOf=
"@+id/image_view_medium_dark_tone"
app:srcCompat=
"@drawable/color_change_circle"
app:srcCompat=
"@drawable/bg_skin_tone"
/>
tools:text=
"👌"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
emoji/src/main/res/layout/emoji_keyboard.xml
View file @
ee16b416
...
@@ -43,7 +43,7 @@
...
@@ -43,7 +43,7 @@
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:srcCompat=
"@drawable/
color_change_circl
e"
/>
app:srcCompat=
"@drawable/
bg_skin_ton
e"
/>
<ImageView
<ImageView
android:id=
"@+id/emoji_search"
android:id=
"@+id/emoji_search"
...
...
emoji/src/main/res/values/strings.xml
View file @
ee16b416
<resources>
<resources>
<string
name=
"msg_no_recent_emoji"
>
No recent emoji
</string>
<string
name=
"msg_no_recent_emoji"
>
No recent emoji
</string>
<string
name=
"alert_title_default_skin_tone"
>
Default skin tone
</string>
<string
name=
"alert_title_default_skin_tone"
>
Default skin tone
</string>
<string
name=
"msg_reactions"
translatable=
"false"
>
Reactions
</string>
</resources>
</resources>
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