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
83de162a
Unverified
Commit
83de162a
authored
Nov 26, 2018
by
Divyanshu Bhargava
Committed by
GitHub
Nov 26, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #66 from RocketChat/develop
merge
parents
6c69063b
4c9ae11a
Changes
55
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
55 changed files
with
1170 additions
and
333 deletions
+1170
-333
file_paths.xml
app/src/debug/res/xml/file_paths.xml
+6
-0
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+10
-1
ServerFragment.kt
...rocket/android/authentication/server/ui/ServerFragment.kt
+37
-8
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
+112
-78
ChatRoomView.kt
...chat/rocket/android/chatroom/presentation/ChatRoomView.kt
+3
-10
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+109
-24
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
+3
-0
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
+22
-1
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+1
-2
DatabaseManager.kt
app/src/main/java/chat/rocket/android/db/DatabaseManager.kt
+43
-37
FavoriteMessagesPresenter.kt
...avoritemessages/presentation/FavoriteMessagesPresenter.kt
+2
-1
FilesPresenter.kt
.../chat/rocket/android/files/presentation/FilesPresenter.kt
+1
-0
MainActivity.kt
...src/main/java/chat/rocket/android/main/ui/MainActivity.kt
+0
-3
MembersPresenter.kt
...t/rocket/android/members/presentation/MembersPresenter.kt
+2
-1
PinnedMessagesPresenter.kt
...id/pinnedmessages/presentation/PinnedMessagesPresenter.kt
+2
-1
ProfilePresenter.kt
...t/rocket/android/profile/presentation/ProfilePresenter.kt
+22
-21
ProfileFragment.kt
...in/java/chat/rocket/android/profile/ui/ProfileFragment.kt
+1
-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
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
message_attachment_options.xml
app/src/main/res/layout/message_attachment_options.xml
+12
-2
reaction_praises_list_item.xml
app/src/main/res/layout/reaction_praises_list_item.xml
+35
-0
update_avatar_options.xml
app/src/main/res/layout/update_avatar_options.xml
+2
-2
strings.xml
app/src/main/res/values-de/strings.xml
+7
-2
strings.xml
app/src/main/res/values-es/strings.xml
+7
-2
strings.xml
app/src/main/res/values-fr/strings.xml
+7
-2
strings.xml
app/src/main/res/values-hi-rIN/strings.xml
+7
-2
strings.xml
app/src/main/res/values-it/strings.xml
+319
-0
strings.xml
app/src/main/res/values-ja/strings.xml
+7
-6
strings.xml
app/src/main/res/values-pt-rBR/strings.xml
+6
-2
strings.xml
app/src/main/res/values-ru-rRU/strings.xml
+8
-2
strings.xml
app/src/main/res/values-tr/strings.xml
+7
-2
strings.xml
app/src/main/res/values-uk/strings.xml
+8
-2
strings.xml
app/src/main/res/values/strings.xml
+6
-2
file_paths.xml
app/src/main/res/xml/file_paths.xml
+6
-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
Image.kt
...src/main/java/chat/rocket/android/util/extension/Image.kt
+18
-0
No files found.
app/src/debug/res/xml/file_paths.xml
0 → 100644
View file @
83de162a
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name=
"rocket_chat_images"
path=
"Android/data/chat.rocket.android.dev/files/Pictures"
/>
</paths>
\ No newline at end of file
app/src/main/AndroidManifest.xml
View file @
83de162a
...
...
@@ -105,6 +105,15 @@
<meta-data
android:name=
"io.fabric.ApiKey"
android:value=
"12ac6e94f850aaffcdff52001af77ca415d06a43"
/>
</application>
<provider
android:name=
"androidx.core.content.FileProvider"
android:authorities=
"chat.rocket.android.fileprovider"
android:exported=
"false"
android:grantUriPermissions=
"true"
>
<meta-data
android:name=
"android.support.FILE_PROVIDER_PATHS"
android:resource=
"@xml/file_paths"
/>
</provider>
</application>
</manifest>
app/src/main/java/chat/rocket/android/authentication/server/ui/ServerFragment.kt
View file @
83de162a
package
chat.rocket.android.authentication.server.ui
import
android.os.Bundle
import
android.text.SpannableStringBuilder
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
...
...
@@ -11,6 +12,7 @@ import android.widget.ScrollView
import
android.widget.Toast
import
androidx.core.content.ContextCompat
import
androidx.core.net.toUri
import
androidx.core.text.color
import
androidx.core.view.ViewCompat
import
androidx.core.view.isVisible
import
androidx.fragment.app.Fragment
...
...
@@ -51,6 +53,8 @@ class ServerFragment : Fragment(), ServerView {
lateinit
var
analyticsManager
:
AnalyticsManager
private
var
deepLinkInfo
:
LoginDeepLinkInfo
?
=
null
private
var
protocol
=
"https://"
private
var
isDomainAppended
=
false
private
var
appendedText
=
""
private
lateinit
var
serverUrlDisposable
:
Disposable
private
val
layoutListener
=
ViewTreeObserver
.
OnGlobalLayoutListener
{
if
(
KeyboardHelper
.
isSoftKeyboardShown
(
scroll_view
.
rootView
))
{
...
...
@@ -131,7 +135,7 @@ class ServerFragment : Fragment(), ServerView {
}
private
fun
setupOnClickListener
()
=
ui
{
_
->
ui
{
button_connect
.
setOnClickListener
{
presenter
.
checkServer
(
"$protocol${text_server_url.textContent.sanitize()}"
)
}
...
...
@@ -244,17 +248,42 @@ class ServerFragment : Fragment(), ServerView {
private
fun
subscribeEditText
()
{
serverUrlDisposable
=
text_server_url
.
asObservable
()
.
filter
{
it
.
isNotBlank
()
}
.
subscribe
{
if
(
"$protocol${it.toString()}"
.
isValidUrl
())
{
enableButtonConnect
()
}
else
{
disableButtonConnect
()
}
}
.
subscribe
{
processUserInput
(
it
.
toString
())
}
}
private
fun
unsubscribeEditText
()
=
serverUrlDisposable
.
dispose
()
private
fun
processUserInput
(
text
:
String
)
{
if
(
text
.
last
().
toString
()
==
"."
&&
!
isDomainAppended
)
{
addDomain
()
}
else
if
(
isDomainAppended
&&
text
!=
appendedText
)
{
removeDomain
()
}
if
(
"$protocol$text"
.
isValidUrl
())
{
enableButtonConnect
()
}
else
{
disableButtonConnect
()
}
}
private
fun
addDomain
()
{
val
cursorPosition
=
text_server_url
.
length
()
text_server_url
.
append
(
SpannableStringBuilder
()
.
color
(
R
.
color
.
colorAuthenticationSecondaryText
)
{
append
(
"rocket.chat"
)
})
text_server_url
.
setSelection
(
cursorPosition
)
appendedText
=
text_server_url
.
text
.
toString
()
isDomainAppended
=
true
}
private
fun
removeDomain
()
{
text_server_url
.
setText
(
text_server_url
.
text
.
toString
().
substring
(
0
,
text_server_url
.
selectionEnd
)
)
text_server_url
.
setSelection
(
text_server_url
.
length
())
isDomainAppended
=
false
}
private
fun
enableUserInput
()
{
enableButtonConnect
()
text_server_url
.
isEnabled
=
true
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/BaseViewHolder.kt
View file @
83de162a
...
...
@@ -61,6 +61,10 @@ abstract class BaseViewHolder<T : BaseUiModel<*>>(
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
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/MessageReactionsAdapter.kt
View file @
83de162a
...
...
@@ -75,7 +75,7 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
class
ReactionViewHolder
(
view
:
View
,
private
val
listener
:
EmojiReactionListener
?
)
:
RecyclerView
.
ViewHolder
(
view
),
View
.
OnClickListener
{
)
:
RecyclerView
.
ViewHolder
(
view
),
View
.
OnClickListener
,
View
.
OnLongClickListener
{
@Inject
lateinit
var
localRepository
:
LocalRepository
...
...
@@ -121,6 +121,8 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
view_flipper_reaction
.
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>()
}
}
}
override
fun
onLongClick
(
v
:
View
?):
Boolean
{
listener
?.
onReactionLongClicked
(
reaction
.
shortname
,
reaction
.
isCustom
,
reaction
.
url
,
reaction
.
usernames
)
return
true
}
}
class
AddReactionViewHolder
(
...
...
app/src/main/java/chat/rocket/android/chatroom/di/ChatRoomFragmentModule.kt
View file @
83de162a
package
chat.rocket.android.chatroom.di
import
android.app.Application
import
androidx.lifecycle.LifecycleOwner
import
chat.rocket.android.chatroom.presentation.ChatRoomView
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.dagger.scope.PerFragment
import
chat.rocket.android.db.ChatRoomDao
import
chat.rocket.android.db.DatabaseManager
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.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.Provides
import
kotlinx.coroutines.experimental.Job
...
...
@@ -42,4 +49,30 @@ class ChatRoomFragmentModule {
@Provides
@PerFragment
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 @
83de162a
This diff is collapsed.
Click to expand it.
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt
View file @
83de162a
...
...
@@ -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.EmojiSuggestionUiModel
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.MessageView
import
chat.rocket.core.internal.realtime.socket.model.State
...
...
@@ -131,12 +132,7 @@ interface ChatRoomView : LoadingView, MessageView {
fun
populateEmojiSuggestions
(
emojis
:
List
<
EmojiSuggestionUiModel
>)
/**
* This user has joined the chat callback.
*
* @param userCanPost Whether the user can post a message or not.
*/
fun
onJoined
(
userCanPost
:
Boolean
)
fun
onJoined
(
roomUiModel
:
RoomUiModel
)
fun
showReactionsPopup
(
messageId
:
String
)
...
...
@@ -147,9 +143,6 @@ interface ChatRoomView : LoadingView, MessageView {
*/
fun
populateCommandSuggestions
(
commands
:
List
<
CommandSuggestionUiModel
>)
/**
* Communicate whether it's a broadcast channel and if current user can post to it.
*/
fun
onRoomUpdated
(
userCanPost
:
Boolean
,
channelIsBroadcast
:
Boolean
,
userCanMod
:
Boolean
)
fun
onRoomUpdated
(
roomUiModel
:
RoomUiModel
)
}
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
83de162a
This diff is collapsed.
Click to expand it.
app/src/main/java/chat/rocket/android/chatroom/uimodel/ReactionUiModel.kt
View file @
83de162a
...
...
@@ -6,5 +6,6 @@ data class ReactionUiModel(
val
unicode
:
CharSequence
,
val
count
:
Int
,
val
usernames
:
List
<
String
>
=
emptyList
(),
var
url
:
String
?
=
null
)
\ No newline at end of file
var
url
:
String
?
=
null
,
val
isCustom
:
Boolean
=
false
)
app/src/main/java/chat/rocket/android/chatroom/uimodel/UiModelMapper.kt
View file @
83de162a
...
...
@@ -19,6 +19,7 @@ import chat.rocket.android.dagger.scope.PerFragment
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.emoji.EmojiParser
import
chat.rocket.android.emoji.EmojiRepository
import
chat.rocket.android.emoji.internal.isCustom
import
chat.rocket.android.helper.MessageHelper
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.helper.UserHelper
...
...
@@ -31,6 +32,7 @@ import chat.rocket.android.server.domain.messageReadReceiptEnabled
import
chat.rocket.android.server.domain.messageReadReceiptStoreUsers
import
chat.rocket.android.server.domain.useRealName
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.ifNotNullNorEmpty
import
chat.rocket.android.util.extensions.isNotNullNorEmpty
...
...
@@ -469,7 +471,7 @@ class UiModelMapper @Inject constructor(
val
list
=
mutableListOf
<
ReactionUiModel
>()
val
customEmojis
=
EmojiRepository
.
getCustomEmojis
()
it
.
getShortNames
().
forEach
{
shortname
->
val
usernames
=
it
.
getUsernames
(
shortname
)
?:
emptyList
()
val
usernames
=
it
.
getUsernames
(
shortname
)
.
orEmpty
()
val
count
=
usernames
.
size
val
custom
=
customEmojis
.
firstOrNull
{
emoji
->
emoji
.
shortname
==
shortname
}
list
.
add
(
...
...
@@ -478,7 +480,8 @@ class UiModelMapper @Inject constructor(
unicode
=
EmojiParser
.
parse
(
context
,
shortname
),
count
=
count
,
usernames
=
usernames
,
url
=
custom
?.
url
)
url
=
custom
?.
url
,
isCustom
=
custom
!=
null
)
)
}
list
...
...
app/src/main/java/chat/rocket/android/chatrooms/adapter/RoomUiModelMapper.kt
View file @
83de162a
...
...
@@ -8,9 +8,8 @@ import androidx.core.text.color
import
chat.rocket.android.R
import
chat.rocket.android.chatrooms.adapter.model.RoomUiModel
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.PermissionsInteractor
import
chat.rocket.android.server.domain.PublicSettings
import
chat.rocket.android.server.domain.showLastMessage
import
chat.rocket.android.server.domain.useRealName
...
...
@@ -30,7 +29,8 @@ class RoomUiModelMapper(
private
val
context
:
Application
,
private
val
settings
:
PublicSettings
,
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
nameColor
=
ContextCompat
.
getColor
(
context
,
R
.
color
.
colorSecondaryText
)
...
...
@@ -97,7 +97,9 @@ class RoomUiModelMapper(
avatar
=
serverUrl
.
avatarUrl
(
name
!!
,
isGroupOrChannel
=
true
),
lastMessage
=
if
(
showLastMessage
)
{
mapLastMessage
(
lastMessage
?.
sender
?.
id
,
lastMessage
?.
sender
?.
username
,
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(
alert
=
isUnread
,
lastMessage
=
lastMessageMarkdown
,
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
{
val
resources
=
context
.
resources
return
when
(
type
)
{
...
...
@@ -205,4 +214,4 @@ class RoomUiModelMapper(
}
}
}
}
\ No newline at end of file
}
app/src/main/java/chat/rocket/android/chatrooms/adapter/model/RoomUiModel.kt
View file @
83de162a
...
...
@@ -15,5 +15,8 @@ data class RoomUiModel(
val
lastMessage
:
CharSequence
?
=
null
,
val
status
:
UserStatus
?
=
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 @
83de162a
...
...
@@ -12,6 +12,7 @@ import chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.db.UserDao
import
chat.rocket.android.infrastructure.LocalRepository
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.SettingsRepository
import
chat.rocket.android.server.domain.TokenRepository
...
...
@@ -88,9 +89,10 @@ class ChatRoomsFragmentModule {
context
:
Application
,
repository
:
SettingsRepository
,
userInteractor
:
GetCurrentUserInteractor
,
@Named
(
"currentServer"
)
serverUrl
:
String
@Named
(
"currentServer"
)
serverUrl
:
String
,
permissionsInteractor
:
PermissionsInteractor
):
RoomUiModelMapper
{
return
RoomUiModelMapper
(
context
,
repository
.
get
(
serverUrl
),
userInteractor
,
serverUrl
)
return
RoomUiModelMapper
(
context
,
repository
.
get
(
serverUrl
),
userInteractor
,
serverUrl
,
permissionsInteractor
)
}
@Provides
...
...
app/src/main/java/chat/rocket/android/chatrooms/infrastructure/ChatRoomsRepository.kt
View file @
83de162a
...
...
@@ -3,9 +3,12 @@ package chat.rocket.android.chatrooms.infrastructure
import
androidx.lifecycle.LiveData
import
chat.rocket.android.db.ChatRoomDao
import
chat.rocket.android.db.model.ChatRoom
import
chat.rocket.android.util.retryDB
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
>>
{
return
when
(
order
)
{
Order
.
ACTIVITY
->
dao
.
getAll
()
...
...
@@ -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
{
ACTIVITY
,
...
...
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
83de162a
...
...
@@ -13,6 +13,7 @@ import chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.server.domain.useSpecialCharsOnRoom
import
chat.rocket.android.server.infraestructure.ConnectionManager
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.retryDB
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.RoomType
...
...
@@ -41,11 +42,31 @@ class ChatRoomsPresenter @Inject constructor(
private
val
client
=
manager
.
client
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
)
{
launchUI
(
strategy
)
{
view
.
showLoadingRoom
(
chatRoom
.
name
)
try
{
val
room
=
dbManager
.
getRoom
(
chatRoom
.
id
)
val
room
=
retryDB
(
"getRoom(${chatRoom.id}"
)
{
dbManager
.
getRoom
(
chatRoom
.
id
)
}
if
(
room
!=
null
)
{
loadChatRoom
(
room
.
chatRoom
,
true
)
}
else
{
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
83de162a
...
...
@@ -84,8 +84,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
chatRoomId
?.
let
{
// TODO - bring back support to load a room from id.
//presenter.goToChatRoomWithId(it)
presenter
.
loadChatRoom
(
it
)
chatRoomId
=
null
}
}
...
...
app/src/main/java/chat/rocket/android/db/DatabaseManager.kt
View file @
83de162a
...
...
@@ -19,6 +19,7 @@ import chat.rocket.android.util.extensions.exhaustive
import
chat.rocket.android.util.extensions.removeTrailingSlash
import
chat.rocket.android.util.extensions.toEntity
import
chat.rocket.android.util.extensions.userId
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.model.BaseRoom
import
chat.rocket.common.model.RoomType
import
chat.rocket.common.model.SimpleUser
...
...
@@ -91,12 +92,14 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
}
}
fun
logout
()
{
database
.
clearAllTables
()
suspend
fun
logout
()
{
retryDB
(
"clearAllTables"
)
{
database
.
clearAllTables
()
}
}
suspend
fun
getRoom
(
id
:
String
)
=
withContext
(
dbManagerContext
)
{
chatRoomDao
().
get
(
id
)
retryDB
(
"getRoom($id)"
)
{
chatRoomDao
().
get
(
id
)
}
}
fun
processUsersBatch
(
users
:
List
<
User
>)
{
...
...
@@ -151,7 +154,7 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
fun
updateSelfUser
(
myself
:
Myself
)
{
launch
(
dbManagerContext
)
{
val
user
=
userDao
().
getUser
(
myself
.
id
)
val
user
=
retryDB
(
"getUser(${myself.id})"
)
{
userDao
().
getUser
(
myself
.
id
)
}
val
entity
=
user
?.
copy
(
name
=
myself
.
name
?:
user
.
name
,
username
=
myself
.
username
?:
user
.
username
,
...
...
@@ -335,7 +338,7 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
}
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
)
{
val
chatRoom
=
current
.
chatRoom
...
...
@@ -373,7 +376,7 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
context
.
getString
(
R
.
string
.
msg_sent_attachment
)
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
)
{
val
userId
=
if
(
type
is
RoomType
.
DirectMessage
)
{
...
...
@@ -539,39 +542,42 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
}
}
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
)
{
when
(
operation
)
{
is
Operation
.
ClearStatus
->
userDao
().
clearStatus
()
is
Operation
.
UpdateRooms
->
{
Timber
.
d
(
"Running ChatRooms transaction: remove: ${operation.toRemove} - insert: ${operation.toInsert} - update: ${operation.toUpdate}"
)
private
suspend
fun
doOperation
(
operation
:
Operation
)
{
retryDB
(
description
=
"doOperation($operation)"
)
{
when
(
operation
)
{
is
Operation
.
ClearStatus
->
userDao
().
clearStatus
()
is
Operation
.
UpdateRooms
->
{
Timber
.
d
(
"Running ChatRooms transaction: remove: ${operation.toRemove} - insert: ${operation.toInsert} - update: ${operation.toUpdate}"
)
chatRoomDao
().
update
(
operation
.
toInsert
,
operation
.
toUpdate
,
operation
.
toRemove
)
}
is
Operation
.
InsertRooms
->
{
chatRoomDao
().
insertOrReplace
(
operation
.
chatRooms
)
}
is
Operation
.
CleanInsertRooms
->
{
chatRoomDao
().
cleanInsert
(
operation
.
chatRooms
)
}
is
Operation
.
InsertUsers
->
{
val
time
=
measureTimeMillis
{
userDao
().
upsert
(
operation
.
users
)
}
Timber
.
d
(
"Upserted users batch(${operation.users.size}) in $time MS"
)
}
is
Operation
.
InsertUser
->
{
userDao
().
insert
(
operation
.
user
)
}
is
Operation
.
UpsertUser
->
{
userDao
().
upsert
(
operation
.
user
)
}
is
Operation
.
InsertMessages
->
{
messageDao
().
insert
(
operation
.
list
)
}
is
Operation
.
SaveLastSync
->
{
messageDao
().
saveLastSync
(
operation
.
sync
)
}
}.
exhaustive
chatRoomDao
().
update
(
operation
.
toInsert
,
operation
.
toUpdate
,
operation
.
toRemove
)
}
is
Operation
.
InsertRooms
->
{
chatRoomDao
().
insertOrReplace
(
operation
.
chatRooms
)
}
is
Operation
.
CleanInsertRooms
->
{
chatRoomDao
().
cleanInsert
(
operation
.
chatRooms
)
}
is
Operation
.
InsertUsers
->
{
val
time
=
measureTimeMillis
{
userDao
().
upsert
(
operation
.
users
)
}
Timber
.
d
(
"Upserted users batch(${operation.users.size}) in $time MS"
)
}
is
Operation
.
InsertUser
->
{
userDao
().
insert
(
operation
.
user
)
}
is
Operation
.
UpsertUser
->
{
userDao
().
upsert
(
operation
.
user
)
}
is
Operation
.
InsertMessages
->
{
messageDao
().
insert
(
operation
.
list
)
}
is
Operation
.
SaveLastSync
->
{
messageDao
().
saveLastSync
(
operation
.
sync
)
}
}.
exhaustive
}
}
}
...
...
app/src/main/java/chat/rocket/android/favoritemessages/presentation/FavoriteMessagesPresenter.kt
View file @
83de162a
...
...
@@ -5,6 +5,7 @@ import chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
...
...
@@ -36,7 +37,7 @@ class FavoriteMessagesPresenter @Inject constructor(
view
.
showLoading
()
dbManager
.
getRoom
(
roomId
)
?.
let
{
val
favoriteMessages
=
client
.
getFavoriteMessages
(
roomId
,
roomTypeOf
(
it
.
chatRoom
.
type
),
offset
)
client
.
getFavoriteMessages
(
roomId
,
roomTypeOf
(
it
.
chatRoom
.
type
),
offset
)
val
messageList
=
mapper
.
map
(
favoriteMessages
.
result
,
asNotReversed
=
true
)
view
.
showFavoriteMessages
(
messageList
)
offset
+=
1
*
30
...
...
app/src/main/java/chat/rocket/android/files/presentation/FilesPresenter.kt
View file @
83de162a
...
...
@@ -7,6 +7,7 @@ import chat.rocket.android.files.uimodel.FileUiModel
import
chat.rocket.android.files.uimodel.FileUiModelMapper
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
...
...
app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt
View file @
83de162a
...
...
@@ -62,10 +62,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
setContentView
(
R
.
layout
.
activity_main
)
refreshPushToken
()
chatRoomId
=
intent
.
getStringExtra
(
INTENT_CHAT_ROOM_ID
)
println
(
"ChatRoomId: $chatRoomId"
)
presenter
.
clearNotificationsForChatroom
(
chatRoomId
)
presenter
.
connect
()
...
...
app/src/main/java/chat/rocket/android/members/presentation/MembersPresenter.kt
View file @
83de162a
...
...
@@ -6,6 +6,7 @@ import chat.rocket.android.members.uimodel.MemberUiModel
import
chat.rocket.android.members.uimodel.MemberUiModelMapper
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
...
...
@@ -38,7 +39,7 @@ class MembersPresenter @Inject constructor(
view
.
showLoading
()
dbManager
.
getRoom
(
roomId
)
?.
let
{
val
members
=
client
.
getMembers
(
roomId
,
roomTypeOf
(
it
.
chatRoom
.
type
),
offset
,
60
)
client
.
getMembers
(
roomId
,
roomTypeOf
(
it
.
chatRoom
.
type
),
offset
,
60
)
val
memberUiModels
=
mapper
.
mapToUiModelList
(
members
.
result
)
view
.
showMembers
(
memberUiModels
,
members
.
total
)
offset
+=
1
*
60L
...
...
app/src/main/java/chat/rocket/android/pinnedmessages/presentation/PinnedMessagesPresenter.kt
View file @
83de162a
...
...
@@ -5,6 +5,7 @@ import chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
...
...
@@ -36,7 +37,7 @@ class PinnedMessagesPresenter @Inject constructor(
view
.
showLoading
()
dbManager
.
getRoom
(
roomId
)
?.
let
{
val
pinnedMessages
=
client
.
getPinnedMessages
(
roomId
,
roomTypeOf
(
it
.
chatRoom
.
type
),
offset
)
client
.
getPinnedMessages
(
roomId
,
roomTypeOf
(
it
.
chatRoom
.
type
),
offset
)
val
messageList
=
mapper
.
map
(
pinnedMessages
.
result
,
asNotReversed
=
true
)
view
.
showPinnedMessages
(
messageList
)
offset
+=
1
*
30
...
...
app/src/main/java/chat/rocket/android/profile/presentation/ProfilePresenter.kt
View file @
83de162a
...
...
@@ -29,7 +29,6 @@ import chat.rocket.core.internal.rest.setAvatar
import
chat.rocket.core.internal.rest.updateProfile
import
kotlinx.coroutines.experimental.DefaultDispatcher
import
kotlinx.coroutines.experimental.withContext
import
java.lang.Exception
import
java.util.*
import
javax.inject.Inject
...
...
@@ -58,20 +57,17 @@ class ProfilePresenter @Inject constructor(
)
{
private
val
serverUrl
=
serverInteractor
.
get
()
!!
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverUrl
)
private
val
myselfId
=
userHelper
.
user
()
?.
id
?:
""
private
var
myselfName
=
userHelper
.
user
()
?.
name
?:
""
private
var
myselfUsername
=
userHelper
.
username
()
?:
""
private
var
myselfEmailAddress
=
userHelper
.
user
()
?.
emails
?.
getOrNull
(
0
)
?.
address
?:
""
private
val
user
=
userHelper
.
user
()
fun
loadUserProfile
()
{
launchUI
(
strategy
)
{
view
.
showLoading
()
try
{
view
.
showProfile
(
serverUrl
.
avatarUrl
(
myselfUsername
),
myselfName
,
myselfUsername
,
myselfEmailAddress
serverUrl
.
avatarUrl
(
user
?.
username
?:
""
),
user
?.
name
?:
""
,
user
?.
username
?:
""
,
user
?.
emails
?.
getOrNull
(
0
)
?.
address
?:
""
)
}
catch
(
exception
:
RocketChatException
)
{
view
.
showMessage
(
exception
)
...
...
@@ -85,14 +81,16 @@ class ProfilePresenter @Inject constructor(
launchUI
(
strategy
)
{
view
.
showLoading
()
try
{
retryIO
{
client
.
updateProfile
(
myselfId
,
email
,
name
,
username
)
}
myselfEmailAddress
=
email
myselfName
=
name
myselfUsername
=
username
view
.
showProfileUpdateSuccessfullyMessage
()
loadUserProfile
()
user
?.
id
?.
let
{
id
->
retryIO
{
client
.
updateProfile
(
id
,
email
,
name
,
username
)
}
view
.
showProfileUpdateSuccessfullyMessage
()
view
.
showProfile
(
serverUrl
.
avatarUrl
(
user
.
username
?:
""
),
name
,
username
,
email
)
}
}
catch
(
exception
:
RocketChatException
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
...
...
@@ -117,7 +115,7 @@ class ProfilePresenter @Inject constructor(
uriInteractor
.
getInputStream
(
uri
)
}
}
view
.
reloadUserAvatar
(
serverUrl
.
avatarUrl
(
myselfUsername
))
user
?.
username
?.
let
{
view
.
reloadUserAvatar
(
it
)
}
}
catch
(
exception
:
RocketChatException
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
...
...
@@ -144,7 +142,8 @@ class ProfilePresenter @Inject constructor(
byteArray
?.
inputStream
()
}
}
view
.
reloadUserAvatar
(
serverUrl
.
avatarUrl
(
myselfUsername
))
user
?.
username
?.
let
{
view
.
reloadUserAvatar
(
it
)
}
}
catch
(
exception
:
RocketChatException
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
...
...
@@ -161,8 +160,10 @@ class ProfilePresenter @Inject constructor(
launchUI
(
strategy
)
{
view
.
showLoading
()
try
{
retryIO
{
client
.
resetAvatar
(
myselfId
)
}
view
.
reloadUserAvatar
(
serverUrl
.
avatarUrl
(
myselfUsername
))
user
?.
id
?.
let
{
id
->
retryIO
{
client
.
resetAvatar
(
id
)
}
}
user
?.
username
?.
let
{
view
.
reloadUserAvatar
(
it
)
}
}
catch
(
exception
:
RocketChatException
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
...
...
app/src/main/java/chat/rocket/android/profile/ui/ProfileFragment.kt
View file @
83de162a
...
...
@@ -217,7 +217,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
hideUpdateAvatarOptions
()
}
button_take_photo
.
setOnClickListener
{
button_take_
a_
photo
.
setOnClickListener
{
dispatchTakePicture
(
REQUEST_CODE_FOR_PERFORM_CAMERA
)
hideUpdateAvatarOptions
()
}
...
...
app/src/main/java/chat/rocket/android/push/PushManager.kt
View file @
83de162a
...
...
@@ -296,11 +296,8 @@ class PushManager @Inject constructor(
}
private
fun
getContentIntent
(
context
:
Context
,
notificationId
:
Int
,
pushMessage
:
PushMessage
,
grouped
:
Boolean
=
false
):
PendingIntent
{
val
notificationIntent
=
context
.
changeServerIntent
(
pushMessage
.
info
.
host
,
chatRoomId
=
pushMessage
.
info
.
roomId
)
// TODO - add support to go directly to the chatroom
/*if (!isGrouped) {
notificationIntent.putExtra(EXTRA_ROOM_ID, pushMessage.info.roomId)
}*/
val
roomId
=
if
(!
grouped
)
pushMessage
.
info
.
roomId
else
null
val
notificationIntent
=
context
.
changeServerIntent
(
pushMessage
.
info
.
host
,
chatRoomId
=
roomId
)
return
PendingIntent
.
getActivity
(
context
,
random
.
nextInt
(),
notificationIntent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
)
}
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/ConnectionManager.kt
View file @
83de162a
...
...
@@ -22,6 +22,7 @@ import chat.rocket.core.internal.realtime.unsubscribe
import
chat.rocket.core.internal.rest.chatRooms
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Myself
import
chat.rocket.core.model.Room
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.Job
import
kotlinx.coroutines.experimental.channels.Channel
...
...
@@ -45,6 +46,7 @@ class ConnectionManager(
private
val
roomMessagesChannels
=
LinkedHashMap
<
String
,
Channel
<
Message
>>()
private
val
userDataChannels
=
ArrayList
<
Channel
<
Myself
>>()
private
val
roomsChannels
=
LinkedHashMap
<
String
,
Channel
<
Room
>>()
private
val
subscriptionIdMap
=
HashMap
<
String
,
String
>()
private
var
subscriptionId
:
String
?
=
null
...
...
@@ -127,6 +129,18 @@ class ConnectionManager(
maxSize
=
10
)
{
batch
->
Timber
.
d
(
"processing Stream batch: ${batch.size} - $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
,
...
...
@@ -241,6 +255,14 @@ class ConnectionManager(
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
>)
{
val
oldSub
=
roomMessagesChannels
.
put
(
roomId
,
channel
)
if
(
oldSub
!=
null
)
{
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/DatabaseMessageMapper.kt
View file @
83de162a
...
...
@@ -7,6 +7,7 @@ import chat.rocket.android.db.model.FullMessage
import
chat.rocket.android.db.model.ReactionEntity
import
chat.rocket.android.db.model.UrlEntity
import
chat.rocket.android.db.model.UserEntity
import
chat.rocket.android.util.retryDB
import
chat.rocket.common.model.SimpleRoom
import
chat.rocket.common.model.SimpleUser
import
chat.rocket.core.model.Message
...
...
@@ -135,14 +136,18 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
with
(
attachment
)
{
val
fields
=
if
(
hasFields
)
{
withContext
(
CommonPool
)
{
dbManager
.
messageDao
().
getAttachmentFields
(
attachment
.
_id
)
retryDB
(
"getAttachmentFields(${attachment._id})"
)
{
dbManager
.
messageDao
().
getAttachmentFields
(
attachment
.
_id
)
}
}.
map
{
Field
(
it
.
title
,
it
.
value
)
}
}
else
{
null
}
val
actions
=
if
(
hasActions
)
{
withContext
(
CommonPool
)
{
dbManager
.
messageDao
().
getAttachmentActions
(
attachment
.
_id
)
retryDB
(
"getAttachmentActions(${attachment._id})"
)
{
dbManager
.
messageDao
().
getAttachmentActions
(
attachment
.
_id
)
}
}.
mapNotNull
{
mapAction
(
it
)
}
}
else
{
null
...
...
@@ -183,29 +188,6 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
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
?
{
return
when
(
action
.
type
)
{
"button"
->
ButtonAction
(
action
.
type
,
action
.
text
,
action
.
url
,
action
.
isWebView
,
...
...
@@ -214,13 +196,4 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
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 @
83de162a
...
...
@@ -4,6 +4,7 @@ import chat.rocket.android.db.DatabaseManager
import
chat.rocket.android.db.Operation
import
chat.rocket.android.db.model.MessagesSync
import
chat.rocket.android.server.domain.MessagesRepository
import
chat.rocket.android.util.retryDB
import
chat.rocket.core.model.Message
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.withContext
...
...
@@ -14,25 +15,31 @@ class DatabaseMessagesRepository(
)
:
MessagesRepository
{
override
suspend
fun
getById
(
id
:
String
):
Message
?
=
withContext
(
CommonPool
)
{
dbManager
.
messageDao
().
getMessageById
(
id
)
?.
let
{
message
->
mapper
.
map
(
message
)
}
retryDB
(
"getMessageById($id)"
)
{
dbManager
.
messageDao
().
getMessageById
(
id
)
?.
let
{
message
->
mapper
.
map
(
message
)
}
}
}
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
// duplicate rows (something related to our JOINS and relations on Room)
dbManager
.
messageDao
().
getMessagesByRoomId
(
roomId
)
.
distinctBy
{
it
.
message
.
message
.
id
}
.
let
{
messages
->
mapper
.
map
(
messages
)
}
retryDB
(
"getMessagesByRoomId($roomId)"
)
{
dbManager
.
messageDao
().
getMessagesByRoomId
(
roomId
)
.
distinctBy
{
it
.
message
.
message
.
id
}
.
let
{
messages
->
mapper
.
map
(
messages
)
}
}
}
override
suspend
fun
getRecentMessages
(
roomId
:
String
,
count
:
Long
):
List
<
Message
>
=
withContext
(
CommonPool
)
{
dbManager
.
messageDao
().
getRecentMessagesByRoomId
(
roomId
,
count
)
.
distinctBy
{
it
.
message
.
message
.
id
}
.
let
{
messages
->
mapper
.
map
(
messages
)
}
retryDB
(
"getRecentMessagesByRoomId($roomId, $count)"
)
{
dbManager
.
messageDao
().
getRecentMessagesByRoomId
(
roomId
,
count
)
.
distinctBy
{
it
.
message
.
message
.
id
}
.
let
{
messages
->
mapper
.
map
(
messages
)
}
}
}
override
suspend
fun
save
(
message
:
Message
)
{
...
...
@@ -45,20 +52,24 @@ class DatabaseMessagesRepository(
override
suspend
fun
removeById
(
id
:
String
)
{
withContext
(
CommonPool
)
{
dbManager
.
messageDao
().
delete
(
id
)
retryDB
(
"delete($id)"
)
{
dbManager
.
messageDao
().
delete
(
id
)
}
}
}
override
suspend
fun
removeByRoomId
(
roomId
:
String
)
{
withContext
(
CommonPool
)
{
dbManager
.
messageDao
().
deleteByRoomId
(
roomId
)
retryDB
(
"deleteByRoomId($roomId)"
)
{
dbManager
.
messageDao
().
deleteByRoomId
(
roomId
)
}
}
}
override
suspend
fun
getAllUnsent
():
List
<
Message
>
=
withContext
(
CommonPool
)
{
dbManager
.
messageDao
().
getUnsentMessages
()
.
distinctBy
{
it
.
message
.
message
.
id
}
.
let
{
mapper
.
map
(
it
)
}
retryDB
(
"getUnsentMessages"
)
{
dbManager
.
messageDao
().
getUnsentMessages
()
.
distinctBy
{
it
.
message
.
message
.
id
}
.
let
{
mapper
.
map
(
it
)
}
}
}
override
suspend
fun
saveLastSyncDate
(
roomId
:
String
,
timeMillis
:
Long
)
{
...
...
@@ -66,6 +77,8 @@ class DatabaseMessagesRepository(
}
override
suspend
fun
getLastSyncDate
(
roomId
:
String
):
Long
?
=
withContext
(
CommonPool
)
{
dbManager
.
messageDao
().
getLastSync
(
roomId
)
?.
let
{
it
.
timestamp
}
retryDB
(
"getLastSync($roomId)"
)
{
dbManager
.
messageDao
().
getLastSync
(
roomId
)
?.
let
{
it
.
timestamp
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/IO.kt
View file @
83de162a
package
chat.rocket.android.util
import
android.database.sqlite.SQLiteDatabaseLockedException
import
chat.rocket.common.RocketChatNetworkErrorException
import
kotlinx.coroutines.experimental.TimeoutCancellationException
import
kotlinx.coroutines.experimental.delay
...
...
@@ -8,6 +9,7 @@ import timber.log.Timber
import
kotlin.coroutines.experimental.coroutineContext
const
val
DEFAULT_RETRY
=
3
private
const
val
DEFAULT_DB_RETRY
=
5
suspend
fun
<
T
>
retryIO
(
description
:
String
=
"<missing description>"
,
...
...
@@ -32,6 +34,33 @@ suspend fun <T> retryIO(
currentDelay
=
(
currentDelay
*
factor
).
toLong
().
coerceAtMost
(
maxDelay
)
}
if
(!
coroutineContext
.
isActive
)
throw
TimeoutCancellationException
(
"job canceled"
)
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 @
83de162a
<?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 @
83de162a
<?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/message_attachment_options.xml
View file @
83de162a
...
...
@@ -6,14 +6,24 @@
android:orientation=
"vertical"
>
<Button
android:id=
"@+id/button_files"
android:id=
"@+id/button_take_a_photo"
style=
"?android:attr/borderlessButtonStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:drawablePadding=
"20dp"
android:drawableStart=
"@drawable/ic_photo_camera_black_24dp"
android:gravity=
"start|center"
android:text=
"@string/action_take_a_photo"
/>
<Button
android:id=
"@+id/button_attach_a_file"
style=
"?android:attr/borderlessButtonStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:drawablePadding=
"20dp"
android:drawableStart=
"@drawable/ic_files_24dp"
android:gravity=
"start|center"
android:text=
"@string/action_files"
/>
android:text=
"@string/action_
attach_a_
files"
/>
<Button
android:id=
"@+id/button_drawing"
...
...
app/src/main/res/layout/reaction_praises_list_item.xml
0 → 100644
View file @
83de162a
<?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/layout/update_avatar_options.xml
View file @
83de162a
...
...
@@ -16,14 +16,14 @@
android:text=
"@string/action_select_photo_from_gallery"
/>
<Button
android:id=
"@+id/button_take_photo"
android:id=
"@+id/button_take_
a_
photo"
style=
"?android:attr/borderlessButtonStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:drawableStart=
"@drawable/ic_photo_camera_black_24dp"
android:drawablePadding=
"20dp"
android:gravity=
"start|center"
android:text=
"@string/action_take_photo"
/>
android:text=
"@string/action_take_
a_
photo"
/>
<Button
android:id=
"@+id/button_reset_avatar"
...
...
app/src/main/res/values-de/strings.xml
View file @
83de162a
...
...
@@ -35,7 +35,7 @@
<string
name=
"action_create_channel"
>
Erstelle Raum
</string>
<string
name=
"action_create"
>
Erstelle
</string>
<string
name=
"action_logout"
>
Abmelden
</string>
<string
name=
"action_
files"
>
Dateien
</string
>
<string
name=
"action_
attach_a_files"
>
Attach a file
</string>
<!-- TODO Add translation --
>
<string
name=
"action_confirm_password"
>
Bestätige Passwort Änderung
</string>
<string
name=
"action_join_chat"
>
Trete Chat bei
</string>
<string
name=
"action_add_account"
>
Erstelle Account
</string>
...
...
@@ -46,7 +46,7 @@
<string
name=
"action_drawing"
>
Zeichnung
</string>
<string
name=
"action_save_to_gallery"
>
Sichern in Gallerie
</string>
<string
name=
"action_select_photo_from_gallery"
>
Select photo from gallery
</string>
<!-- TODO Add translation -->
<string
name=
"action_take_
photo"
>
Select photo from gal
lery
</string>
<!-- TODO Add translation -->
<string
name=
"action_take_
a_photo"
>
Take a photo from ga
lery
</string>
<!-- TODO Add translation -->
<string
name=
"action_reset_avatar"
>
Reset avatar
</string>
<!-- TODO Add translation -->
<string
name=
"action_connect_server"
>
Connect with a server
</string>
<!-- TODO Add translation -->
<string
name=
"action_join_community"
>
Join in the community
</string>
<!-- TODO Add translation -->
...
...
@@ -152,6 +152,11 @@
<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 -->
<string
name=
"msg_private_channel"
>
Privat
</string>
...
...
app/src/main/res/values-es/strings.xml
View file @
83de162a
...
...
@@ -34,7 +34,7 @@
<string
name=
"action_create_channel"
>
Crear canal
</string>
<string
name=
"action_create"
>
Create
</string>
<string
name=
"action_logout"
>
Cerrar sesión
</string>
<string
name=
"action_
files"
>
Archivos
</string
>
<string
name=
"action_
attach_a_files"
>
Attach a file
</string>
<!-- TODO Add translation --
>
<string
name=
"action_confirm_password"
>
Confirmar cambio de contraseña
</string>
<string
name=
"action_join_chat"
>
Unirse al chat
</string>
<string
name=
"action_add_account"
>
Añadir cuenta
</string>
...
...
@@ -45,7 +45,7 @@
<string
name=
"action_drawing"
>
Dibujo
</string>
<string
name=
"action_save_to_gallery"
>
Guardar en la galería
</string>
<string
name=
"action_select_photo_from_gallery"
>
Select photo from gallery
</string>
<!-- TODO Add translation -->
<string
name=
"action_take_
photo"
>
Select photo from gallery
</string>
<!-- TODO Add translation -->
<string
name=
"action_take_
a_photo"
>
Take a photo
</string>
<!-- TODO Add translation -->
<string
name=
"action_reset_avatar"
>
Reset avatar
</string>
<!-- TODO Add translation -->
<string
name=
"action_connect_server"
>
Connect with a server
</string>
<!-- TODO Add translation -->
<string
name=
"action_join_community"
>
Join in the community
</string>
<!-- TODO Add translation -->
...
...
@@ -170,6 +170,11 @@
<string
name=
"msg_permalink_copied"
>
Permalink copied
</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>
<item
quantity=
"other"
>
%1$s reacted with %2$s
</item>
</plurals>
<!-- Preferences messages -->
<string
name=
"msg_analytics_tracking"
>
Analytics tracking
</string>
<!-- TODO Add translation -->
...
...
app/src/main/res/values-fr/strings.xml
View file @
83de162a
...
...
@@ -35,7 +35,7 @@
<string
name=
"action_create_channel"
>
Créer salon
</string>
<string
name=
"action_create"
>
Créer
</string>
<string
name=
"action_logout"
>
Se déconnecter
</string>
<string
name=
"action_
files"
>
Fichiers
</string
>
<string
name=
"action_
attach_a_files"
>
Attach a file
</string>
<!-- TODO Add translation --
>
<string
name=
"action_confirm_password"
>
Confirmer le mot de passe
</string>
<string
name=
"action_join_chat"
>
Rejoignez le chat
</string>
<string
name=
"action_add_account"
>
Ajouter un compte
</string>
...
...
@@ -46,7 +46,7 @@
<string
name=
"action_drawing"
>
Dessin
</string>
<string
name=
"action_save_to_gallery"
>
Sauvegarder vers la gallerie
</string>
<string
name=
"action_select_photo_from_gallery"
>
Sélectionner depuis la gallerie
</string>
<string
name=
"action_take_photo"
>
Prendre une photo
</string>
<string
name=
"action_take_
a_
photo"
>
Prendre une photo
</string>
<string
name=
"action_reset_avatar"
>
Réinitialiser l\'avatar
</string>
<string
name=
"action_connect_server"
>
Connect with a server
</string>
<!-- TODO Add translation -->
<string
name=
"action_join_community"
>
Join in the community
</string>
<!-- TODO Add translation -->
...
...
@@ -162,6 +162,11 @@
<string
name=
"msg_permalink_copied"
>
Permalink copied
</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>
<item
quantity=
"other"
>
%1$s reacted with %2$s
</item>
</plurals>
<!-- Create channel messages -->
<string
name=
"msg_private_channel"
>
Privé
</string>
...
...
app/src/main/res/values-hi-rIN/strings.xml
View file @
83de162a
...
...
@@ -35,7 +35,7 @@
<string
name=
"action_create_channel"
>
चैनल बनाएं
</string>
<string
name=
"action_create"
>
बनाएं
</string>
<string
name=
"action_logout"
>
लोग आउट करें
</string>
<string
name=
"action_
files"
>
फ़ाइलें
</string
>
<string
name=
"action_
attach_a_files"
>
Attach a file
</string>
<!-- TODO Add translation --
>
<string
name=
"action_confirm_password"
>
पासवर्ड परिवर्तन की पुष्टि करें
</string>
<string
name=
"action_join_chat"
>
चैट में शामिल हों
</string>
<string
name=
"action_add_account"
>
खाता जोड़ो
</string>
...
...
@@ -46,7 +46,7 @@
<string
name=
"action_save_to_gallery"
>
गैलरी में सहेजें
</string>
<string
name=
"action_drawing"
>
चित्रकारी
</string>
<string
name=
"action_select_photo_from_gallery"
>
गैलरी से फोटो का चयन करें
</string>
<string
name=
"action_take_photo"
>
फोटो खेचिये
</string>
<string
name=
"action_take_
a_
photo"
>
फोटो खेचिये
</string>
<string
name=
"action_reset_avatar"
>
अवतार रीसेट करें
</string>
<string
name=
"action_connect_server"
>
सर्वर से कनेक्ट करें
</string>
<string
name=
"action_join_community"
>
समुदाय में शामिल हों
</string>
...
...
@@ -174,6 +174,11 @@
<string
name=
"msg_permalink_copied"
>
Permalink copied
</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>
<item
quantity=
"other"
>
%1$s reacted with %2$s
</item>
</plurals>
<!-- Preferences messages -->
<string
name=
"msg_analytics_tracking"
>
एनालिटिक्स ट्रैकिंग
</string>
...
...
app/src/main/res/values-it/strings.xml
0 → 100644
View file @
83de162a
This diff is collapsed.
Click to expand it.
app/src/main/res/values-ja/strings.xml
View file @
83de162a
...
...
@@ -26,9 +26,6 @@
<string
name=
"title_create_channel"
>
新しいチャネルを作成
</string>
<string
name=
"title_are_you_sure"
>
本気ですか?
</string>
<!-- Actions -->
<string
name=
"action_connect"
>
接続
</string>
<string
name=
"action_use_this_username"
>
このユーザー名を使用する
</string>
...
...
@@ -40,7 +37,7 @@
<string
name=
"action_create_channel"
>
チャンネル作成
</string>
<string
name=
"action_create"
>
作ります
</string>
<string
name=
"action_logout"
>
ログアウト
</string>
<string
name=
"action_
files"
>
ファイル
</string
>
<string
name=
"action_
attach_a_files"
>
Attach a file
</string>
<!-- TODO Add translation --
>
<string
name=
"action_confirm_password"
>
変更したパスワードの確認
</string>
<string
name=
"action_join_chat"
>
チャットに参加
</string>
<string
name=
"action_add_account"
>
サーバーの追加
</string>
...
...
@@ -51,7 +48,7 @@
<string
name=
"action_drawing"
>
絵を描く
</string>
<string
name=
"action_save_to_gallery"
>
ギャラリーに保存
</string>
<string
name=
"action_select_photo_from_gallery"
>
ギャラリーの写真を選択
</string>
<string
name=
"action_take_photo"
>
写真を撮る
</string>
<string
name=
"action_take_
a_
photo"
>
写真を撮る
</string>
<string
name=
"action_reset_avatar"
>
アバターをリセット
</string>
<string
name=
"action_connect_server"
>
サーバーに接続
</string>
<string
name=
"action_join_community"
>
コミュニティに参加
</string>
...
...
@@ -161,7 +158,11 @@
<string
name=
"msg_view_more"
>
更に表示
</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 -->
<string
name=
"msg_private_channel"
>
プライベート
</string>
...
...
app/src/main/res/values-pt-rBR/strings.xml
View file @
83de162a
...
...
@@ -35,7 +35,7 @@
<string
name=
"action_create_channel"
>
Criar chat
</string>
<string
name=
"action_create"
>
Criar
</string>
<string
name=
"action_logout"
>
Sair
</string>
<string
name=
"action_
files"
>
Arquivos
</string>
<string
name=
"action_
attach_a_files"
>
Anexar um arquivo
</string>
<string
name=
"action_confirm_password"
>
Confirme a nova senha
</string>
<string
name=
"action_join_chat"
>
Entrar no Chat
</string>
<string
name=
"action_add_account"
>
Adicionar conta
</string>
...
...
@@ -46,7 +46,7 @@
<string
name=
"action_drawing"
>
Desenhando
</string>
<string
name=
"action_save_to_gallery"
>
Salvar na galeria
</string>
<string
name=
"action_select_photo_from_gallery"
>
Escolher foto da galeria
</string>
<string
name=
"action_take_
photo"
>
Tirar
foto
</string>
<string
name=
"action_take_
a_photo"
>
Tirar uma
foto
</string>
<string
name=
"action_reset_avatar"
>
Resetar avatar
</string>
<string
name=
"action_connect_server"
>
Conectar com um servidor
</string>
<string
name=
"action_join_community"
>
Junte-se à comunidade
</string>
...
...
@@ -160,6 +160,10 @@
<!-- TODO - Add proper translation -->
<string
name=
"msg_permalink_copied"
>
Permalink copiado
</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 -->
<string
name=
"msg_private_channel"
>
Privado
</string>
...
...
app/src/main/res/values-ru-rRU/strings.xml
View file @
83de162a
...
...
@@ -35,7 +35,7 @@
<string
name=
"action_create_channel"
>
Создать канал
</string>
<string
name=
"action_create"
>
Создать
</string>
<string
name=
"action_logout"
>
Выйти
</string>
<string
name=
"action_
files"
>
Файлы
</string
>
<string
name=
"action_
attach_a_files"
>
Attach a file
</string>
<!-- TODO Add translation --
>
<string
name=
"action_confirm_password"
>
Подтверждение изменения пароля
</string>
<string
name=
"action_join_chat"
>
Присоединиться к чату
</string>
<string
name=
"action_add_account"
>
Добавить аккаунт
</string>
...
...
@@ -46,7 +46,7 @@
<string
name=
"action_drawing"
>
Рисунок
</string>
<string
name=
"action_save_to_gallery"
>
Сохранить в галерею
</string>
<string
name=
"action_select_photo_from_gallery"
>
Выбрать из галереи
</string>
<string
name=
"action_take_photo"
>
Сделать снимок
</string>
<string
name=
"action_take_
a_
photo"
>
Сделать снимок
</string>
<string
name=
"action_reset_avatar"
>
Восстановить аватар
</string>
<string
name=
"action_connect_server"
>
Соединиться с сервером
</string>
<string
name=
"action_join_community"
>
Сообщество
</string>
...
...
@@ -158,6 +158,12 @@
<string
name=
"msg_permalink_copied"
>
Ссылка скопирована
</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>
<item
quantity=
"few"
>
%1$s reacted with %2$s
</item>
<item
quantity=
"many"
>
%1$s reacted with %2$s
</item>
</plurals>
<!-- Create channel messages -->
<string
name=
"msg_private_channel"
>
Приватный
</string>
...
...
app/src/main/res/values-tr/strings.xml
View file @
83de162a
...
...
@@ -35,7 +35,7 @@
<string
name=
"action_create_channel"
>
Yeni Kanal Oluştur
</string>
<string
name=
"action_create"
>
Oluştur
</string>
<string
name=
"action_logout"
>
Çıkış Yap
</string>
<string
name=
"action_
files"
>
Dosyalar
</string
>
<string
name=
"action_
attach_a_files"
>
Attach a file
</string>
<!-- TODO Add translation --
>
<string
name=
"action_confirm_password"
>
Şifre Değişikliğini Onaylayın
</string>
<string
name=
"action_join_chat"
>
Sohbete Bağlan
</string>
<string
name=
"action_add_account"
>
Hesap Ekle
</string>
...
...
@@ -46,7 +46,7 @@
<string
name=
"action_drawing"
>
Çizim
</string>
<string
name=
"action_save_to_gallery"
>
Galeriye kaydet
</string>
<string
name=
"action_select_photo_from_gallery"
>
Galeriden resim seç
</string>
<string
name=
"action_take_photo"
>
Fotoğraf çek
</string>
<string
name=
"action_take_
a_
photo"
>
Fotoğraf çek
</string>
<string
name=
"action_reset_avatar"
>
Avatarı kaldır
</string>
<string
name=
"action_connect_server"
>
Connect with a server
</string>
<!-- TODO Add translation -->
<string
name=
"action_join_community"
>
Join in the community
</string>
<!-- TODO Add translation -->
...
...
@@ -175,6 +175,11 @@
<string
name=
"msg_permalink_copied"
>
Permalink copied
</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>
<item
quantity=
"other"
>
%1$s reacted with %2$s
</item>
</plurals>
<!-- Preferences messages -->
<string
name=
"msg_analytics_tracking"
>
İstatistik takibi
</string>
...
...
app/src/main/res/values-uk/strings.xml
View file @
83de162a
...
...
@@ -35,7 +35,7 @@
<string
name=
"action_create_channel"
>
Створити канал
</string>
<string
name=
"action_create"
>
Створити
</string>
<string
name=
"action_logout"
>
Вийти
</string>
<string
name=
"action_
files"
>
Файли
</string
>
<string
name=
"action_
attach_a_files"
>
Attach a file
</string>
<!-- TODO Add translation --
>
<string
name=
"action_confirm_password"
>
Підтвердження зміни пароля
</string>
<string
name=
"action_join_chat"
>
Приєднатися до чату
</string>
<string
name=
"action_add_account"
>
Додати аккаунт
</string>
...
...
@@ -46,7 +46,7 @@
<string
name=
"action_drawing"
>
Малюнок
</string>
<string
name=
"action_save_to_gallery"
>
Зберегти до галереї
</string>
<string
name=
"action_select_photo_from_gallery"
>
Вибрати з галереї
</string>
<string
name=
"action_take_photo"
>
Зробити знімок
</string>
<string
name=
"action_take_
a_
photo"
>
Зробити знімок
</string>
<string
name=
"action_reset_avatar"
>
Відновити аватар
</string>
<string
name=
"action_connect_server"
>
Connect with a server
</string>
<!-- TODO Add translation -->
<string
name=
"action_join_community"
>
Join in the community
</string>
<!-- TODO Add translation -->
...
...
@@ -160,6 +160,12 @@
<string
name=
"msg_permalink_copied"
>
Permalink copied
</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>
<item
quantity=
"few"
>
%1$s reacted with %2$s
</item>
<item
quantity=
"many"
>
%1$s reacted with %2$s
</item>
</plurals>
<!-- Create channel messages -->
<string
name=
"msg_private_channel"
>
Приватний
</string>
...
...
app/src/main/res/values/strings.xml
View file @
83de162a
...
...
@@ -47,7 +47,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string
name=
"action_create_channel"
>
Create channel
</string>
<string
name=
"action_create"
>
Create
</string>
<string
name=
"action_logout"
>
Logout
</string>
<string
name=
"action_
files"
>
Files
</string>
<string
name=
"action_
attach_a_files"
>
Attach a file
</string>
<string
name=
"action_confirm_password"
>
Confirm Password Change
</string>
<string
name=
"action_join_chat"
>
Join Chat
</string>
<string
name=
"action_add_account"
>
Add account
</string>
...
...
@@ -58,7 +58,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string
name=
"action_drawing"
>
Drawing
</string>
<string
name=
"action_save_to_gallery"
>
Save to gallery
</string>
<string
name=
"action_select_photo_from_gallery"
>
Select photo from gallery
</string>
<string
name=
"action_take_
photo"
>
Take
photo
</string>
<string
name=
"action_take_
a_photo"
>
Take a
photo
</string>
<string
name=
"action_reset_avatar"
>
Reset avatar
</string>
<string
name=
"action_connect_server"
>
Connect with a server
</string>
<string
name=
"action_join_community"
>
Join in the community
</string>
...
...
@@ -168,6 +168,10 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string
name=
"msg_two_factor_authentication"
>
Two-factor Authentication
</string>
<string
name=
"msg__your_2fa_code"
>
What’s your 2FA code?
</string>
<string
name=
"msg_permalink_copied"
>
Permalink copied
</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 -->
<string
name=
"msg_private_channel"
>
Private
</string>
...
...
app/src/main/res/xml/file_paths.xml
0 → 100644
View file @
83de162a
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name=
"rocket_chat_images"
path=
"Android/data/chat.rocket.android/files/Pictures"
/>
</paths>
\ No newline at end of file
app/src/play/java/chat/rocket/android/push/FirebaseMessagingService.kt
View file @
83de162a
package
chat.rocket.android.push
import
android.os.Bundle
import
androidx.core.os.bundleOf
import
androidx.work.Constraints
import
androidx.work.NetworkType
...
...
@@ -23,9 +24,12 @@ class FirebaseMessagingService : FirebaseMessagingService() {
}
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
{
pushManager
.
handle
(
bundleOf
(*(
it
.
map
{
Pair
(
it
.
key
,
it
.
value
)
}).
toTypedArray
()))
message
.
data
?.
let
{
data
->
val
bundle
=
Bundle
()
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 @
83de162a
...
...
@@ -10,7 +10,6 @@ import android.view.View
import
android.view.ViewGroup
import
android.widget.EditText
import
android.widget.ImageView
import
android.widget.TextView
import
androidx.annotation.ColorInt
import
androidx.appcompat.app.AlertDialog
import
androidx.appcompat.app.AppCompatActivity
...
...
@@ -22,6 +21,7 @@ import chat.rocket.android.emoji.internal.EmojiCategory
import
chat.rocket.android.emoji.internal.EmojiPagerAdapter
import
chat.rocket.android.emoji.internal.PREF_EMOJI_SKIN_TONE
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.launch
...
...
@@ -77,59 +77,50 @@ class EmojiKeyboardPopup(context: Context, view: View) : OverKeyboardPopupWindow
}
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
)
.
setView
(
view
)
.
setTitle
(
context
.
getString
(
R
.
string
.
alert_title_default_skin_tone
))
.
setCancelable
(
true
)
.
create
()
view
.
findViewById
<
TextView
>(
R
.
id
.
default_tone_text
).
also
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
}.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
Default
)
}
with
(
view
)
{
image_view_default_tone
.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
Default
)
}
view
.
findViewById
<
TextView
>(
R
.
id
.
light_tone_text
).
also
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
}.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
LightTone
)
}
image_view_light_tone
.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
LightTone
)
}
view
.
findViewById
<
TextView
>(
R
.
id
.
medium_light_text
).
also
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
}.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
MediumLightTone
)
}
image_view_medium_light
.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
MediumLightTone
)
}
view
.
findViewById
<
TextView
>(
R
.
id
.
medium_tone_text
).
also
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
}.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
MediumTone
)
}
image_view_medium_tone
.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
MediumTone
)
}
view
.
findViewById
<
TextView
>(
R
.
id
.
medium_dark_tone_text
).
also
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
}.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
MediumDarkTone
)
}
image_view_medium_dark_tone
.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
MediumDarkTone
)
}
view
.
findViewById
<
TextView
>(
R
.
id
.
dark_tone_text
).
also
{
it
.
text
=
EmojiParser
.
parse
(
context
,
it
.
text
)
}.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
DarkTone
)
image_view_dark_tone
.
setOnClickListener
{
dialog
.
dismiss
()
changeSkinTone
(
Fitzpatrick
.
DarkTone
)
}
}
dialog
.
show
()
}
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
)
DrawableCompat
.
setTint
(
wrappedDrawable
,
getFitzpatrickColor
(
tone
))
(
changeColorView
as
ImageView
).
setImageDrawable
(
wrappedDrawable
)
...
...
emoji/src/main/java/chat/rocket/android/emoji/EmojiReactionListener.kt
View file @
83de162a
...
...
@@ -16,4 +16,14 @@ interface EmojiReactionListener {
* @param emojiShortname The shortname of the emoji (:grin:, :smiley:, etc).
*/
fun
onReactionTouched
(
messageId
:
String
,
emojiShortname
:
String
)
}
\ No newline at end of file
/**
* 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 @
83de162a
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"oval"
>
<solid
android:color=
"@color/tone_default"
/>
<size
android:width=
"24dp"
android:height=
"24dp"
/>
</shape>
\ No newline at end of file
</shape>
emoji/src/main/res/layout/
color_select_popup
.xml
→
emoji/src/main/res/layout/
dialog_skin_tone_chooser
.xml
View file @
83de162a
<?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=
"wrap_content"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
<
Text
View
android:id=
"@+id/
default_tone_text
"
<
Image
View
android:id=
"@+id/
image_view_default_tone
"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"24dp"
android:layout_marginTop=
"16dp"
android:text=
"👌"
android:textSize=
"32sp"
android:layout_marginBottom=
"16dp"
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_chainStyle=
"
packed
"
app:layout_constraintHorizontal_chainStyle=
"
spread_inside
"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:srcCompat=
"@drawable/
color_change_circl
e"
/>
app:srcCompat=
"@drawable/
bg_skin_ton
e"
/>
<
Text
View
android:id=
"@+id/
light_tone_text
"
<
Image
View
android:id=
"@+id/
image_view_light_tone
"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"24dp"
android:layout_marginTop=
"16dp"
android:layout_marginEnd=
"24dp"
android:text=
"👌🏻"
android:textSize=
"32sp"
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_constraintStart_toEndOf=
"@+id/
default_tone_text
"
app:layout_constraintStart_toEndOf=
"@+id/
image_view_default_tone
"
app:layout_constraintTop_toTopOf=
"parent"
app:srcCompat=
"@drawable/color_change_circle"
tools:text=
"👌"
/>
app:srcCompat=
"@drawable/bg_skin_tone"
/>
<
Text
View
android:id=
"@+id/
medium_light_tex
t"
<
Image
View
android:id=
"@+id/
image_view_medium_ligh
t"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"16dp"
android:text=
"👌🏼"
android:textSize=
"32sp"
android:layout_marginEnd=
"24dp"
android:tint=
"@color/tone_medium_light"
app:layout_constraintEnd_toEndOf=
"parent"
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:srcCompat=
"@drawable/color_change_circle"
tools:text=
"👌"
/>
app:srcCompat=
"@drawable/bg_skin_tone"
/>
<
Text
View
android:id=
"@+id/
medium_tone_text
"
<
Image
View
android:id=
"@+id/
image_view_medium_tone
"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"8dp"
android:layout_marginBottom=
"16dp"
android:text=
"👌🏽"
android:textSize=
"32sp"
android:tint=
"@color/tone_medium"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toStartOf=
"@+id/medium_dark_tone_text"
app:layout_constraintHorizontal_chainStyle=
"packed"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/default_tone_text"
app:srcCompat=
"@drawable/color_change_circle"
tools:text=
"👌"
/>
app:layout_constraintEnd_toStartOf=
"@+id/image_view_medium_dark_tone"
app:layout_constraintHorizontal_chainStyle=
"spread_inside"
app:layout_constraintStart_toStartOf=
"@+id/image_view_default_tone"
app:layout_constraintTop_toBottomOf=
"@+id/image_view_default_tone"
app:srcCompat=
"@drawable/bg_skin_tone"
/>
<
Text
View
android:id=
"@+id/
medium_dark_tone_text
"
<
Image
View
android:id=
"@+id/
image_view_medium_dark_tone
"
android:layout_width=
"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"
app:layout_constraintBottom_toBottomOf=
"
parent
"
app:layout_constraintEnd_toStartOf=
"@+id/
dark_tone_text
"
app:layout_constraintBottom_toBottomOf=
"
@+id/image_view_medium_tone
"
app:layout_constraintEnd_toStartOf=
"@+id/
image_view_dark_tone
"
app:layout_constraintHorizontal_bias=
"0.5"
app:layout_constraintStart_toEndOf=
"@+id/medium_tone_text"
app:layout_constraintTop_toBottomOf=
"@+id/light_tone_text"
app:srcCompat=
"@drawable/color_change_circle"
tools:text=
"👌"
/>
app:layout_constraintStart_toEndOf=
"@+id/image_view_medium_tone"
app:layout_constraintTop_toTopOf=
"@+id/image_view_medium_tone"
app:srcCompat=
"@drawable/bg_skin_tone"
/>
<
Text
View
android:id=
"@+id/
dark_tone_text
"
<
Image
View
android:id=
"@+id/
image_view_dark_tone
"
android:layout_width=
"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"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toEndOf=
"@+id/medium_dark_tone_text"
app:layout_constraintTop_toBottomOf=
"@+id/medium_light_text"
app:srcCompat=
"@drawable/color_change_circle"
tools:text=
"👌"
/>
app:layout_constraintBottom_toBottomOf=
"@+id/image_view_medium_dark_tone"
app:layout_constraintEnd_toEndOf=
"@+id/image_view_medium_light"
app:layout_constraintStart_toEndOf=
"@+id/image_view_medium_dark_tone"
app:layout_constraintTop_toTopOf=
"@+id/image_view_medium_dark_tone"
app:srcCompat=
"@drawable/bg_skin_tone"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
</androidx.constraintlayout.widget.ConstraintLayout>
emoji/src/main/res/layout/emoji_keyboard.xml
View file @
83de162a
...
...
@@ -43,7 +43,7 @@
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:srcCompat=
"@drawable/
color_change_circl
e"
/>
app:srcCompat=
"@drawable/
bg_skin_ton
e"
/>
<ImageView
android:id=
"@+id/emoji_search"
...
...
emoji/src/main/res/values/strings.xml
View file @
83de162a
<resources>
<string
name=
"msg_no_recent_emoji"
>
No recent emoji
</string>
<string
name=
"alert_title_default_skin_tone"
>
Default skin tone
</string>
<string
name=
"msg_reactions"
translatable=
"false"
>
Reactions
</string>
</resources>
util/src/main/java/chat/rocket/android/util/extension/Image.kt
View file @
83de162a
...
...
@@ -2,13 +2,19 @@ package chat.rocket.android.util.extension
import
android.content.Intent
import
android.graphics.Bitmap
import
android.os.Environment
import
android.provider.MediaStore
import
androidx.fragment.app.Fragment
import
androidx.fragment.app.FragmentActivity
import
kotlinx.coroutines.experimental.DefaultDispatcher
import
kotlinx.coroutines.experimental.withContext
import
java.io.ByteArrayInputStream
import
java.io.ByteArrayOutputStream
import
java.io.InputStream
import
java.io.IOException
import
java.io.File
import
java.text.SimpleDateFormat
import
java.util.*
/**
* Compress a [Bitmap] image.
...
...
@@ -104,4 +110,16 @@ fun Fragment.dispatchTakePicture(requestCode: Int) {
if
(
takePictureIntent
.
resolveActivity
(
context
?.
packageManager
)
!=
null
)
{
startActivityForResult
(
takePictureIntent
,
requestCode
)
}
}
@Throws
(
IOException
::
class
)
fun
FragmentActivity
.
createImageFile
():
File
{
// Create an image file name
val
timeStamp
:
String
=
SimpleDateFormat
(
"yyyyMMdd_HHmmss"
).
format
(
Date
())
val
storageDir
:
File
=
getExternalFilesDir
(
Environment
.
DIRECTORY_PICTURES
)
return
File
.
createTempFile
(
"PNG_${timeStamp}_"
,
/* prefix */
".png"
,
/* suffix */
storageDir
/* directory */
)
}
\ No newline at end of file
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