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
6f8195b8
Commit
6f8195b8
authored
May 22, 2018
by
aniket
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into feat/google-smart-lock
parents
7db24109
ca99f416
Changes
50
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
50 changed files
with
1103 additions
and
671 deletions
+1103
-671
build.gradle
app/build.gradle
+1
-1
ChatRoomAdapter.kt
...a/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
+43
-12
ImageAttachmentViewHolder.kt
...ket/android/chatroom/adapter/ImageAttachmentViewHolder.kt
+35
-20
MessageReplyViewHolder.kt
...rocket/android/chatroom/adapter/MessageReplyViewHolder.kt
+30
-0
MessageViewHolder.kt
...chat/rocket/android/chatroom/adapter/MessageViewHolder.kt
+1
-1
MessageReply.kt
.../java/chat/rocket/android/chatroom/domain/MessageReply.kt
+6
-0
ChatRoomNavigator.kt
...rocket/android/chatroom/presentation/ChatRoomNavigator.kt
+22
-2
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+125
-23
ChatRoomView.kt
...chat/rocket/android/chatroom/presentation/ChatRoomView.kt
+13
-3
MessageService.kt
...va/chat/rocket/android/chatroom/service/MessageService.kt
+14
-5
ChatRoomActivity.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
+31
-23
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+109
-56
BaseViewModel.kt
...a/chat/rocket/android/chatroom/viewmodel/BaseViewModel.kt
+2
-1
MessageReplyViewModel.kt
...ocket/android/chatroom/viewmodel/MessageReplyViewModel.kt
+20
-0
RoomViewModel.kt
...a/chat/rocket/android/chatroom/viewmodel/RoomViewModel.kt
+9
-0
ViewModelMapper.kt
...chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
+59
-8
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+28
-13
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+0
-2
ActivityBuilder.kt
...java/chat/rocket/android/dagger/module/ActivityBuilder.kt
+10
-4
FavoriteMessagesFragmentModule.kt
...oid/favoritemessages/di/FavoriteMessagesFragmentModule.kt
+30
-0
FavoriteMessagesFragmentProvider.kt
...d/favoritemessages/di/FavoriteMessagesFragmentProvider.kt
+12
-0
FavoriteMessagesPresenter.kt
...avoritemessages/presentation/FavoriteMessagesPresenter.kt
+52
-0
FavoriteMessagesView.kt
...oid/favoritemessages/presentation/FavoriteMessagesView.kt
+15
-0
FavoriteMessagesFragment.kt
...t/android/favoritemessages/ui/FavoriteMessagesFragment.kt
+119
-0
MessageHelper.kt
...src/main/java/chat/rocket/android/helper/MessageHelper.kt
+71
-0
UserHelper.kt
app/src/main/java/chat/rocket/android/helper/UserHelper.kt
+1
-1
MainNavigator.kt
...va/chat/rocket/android/main/presentation/MainNavigator.kt
+2
-3
MembersFragment.kt
...in/java/chat/rocket/android/members/ui/MembersFragment.kt
+21
-21
PinnedMessagesPresenter.kt
...id/pinnedmessages/presentation/PinnedMessagesPresenter.kt
+2
-2
PinnedMessagesFragment.kt
...ocket/android/pinnedmessages/ui/PinnedMessagesFragment.kt
+24
-23
ChatRoomsInteractor.kt
.../chat/rocket/android/server/domain/ChatRoomsInteractor.kt
+3
-4
ic_arrow_back_white_24dp.xml
app/src/main/res/drawable/ic_arrow_back_white_24dp.xml
+10
-4
ic_hashtag_black.xml
app/src/main/res/drawable/ic_hashtag_black.xml
+0
-12
ic_room_channel.xml
app/src/main/res/drawable/ic_room_channel.xml
+1
-1
ic_room_dm.xml
app/src/main/res/drawable/ic_room_dm.xml
+1
-1
ic_room_lock.xml
app/src/main/res/drawable/ic_room_lock.xml
+1
-1
message_reply_button_bg.xml
app/src/main/res/drawable/message_reply_button_bg.xml
+10
-0
activity_pinned_messages.xml
app/src/main/res/layout/activity_pinned_messages.xml
+0
-19
fragment_favorite_messages.xml
app/src/main/res/layout/fragment_favorite_messages.xml
+77
-0
fragment_pinned_messages.xml
app/src/main/res/layout/fragment_pinned_messages.xml
+18
-22
item_message_reply.xml
app/src/main/res/layout/item_message_reply.xml
+37
-0
chatroom_actions.xml
app/src/main/res/menu/chatroom_actions.xml
+5
-0
strings.xml
app/src/main/res/values-es/strings.xml
+7
-1
strings.xml
app/src/main/res/values-fr/strings.xml
+7
-1
strings.xml
app/src/main/res/values-hi-rIN/strings.xml
+6
-0
strings.xml
app/src/main/res/values-pt-rBR/strings.xml
+6
-0
strings.xml
app/src/main/res/values-uk-rUA/strings.xml
+0
-230
strings.xml
app/src/main/res/values/strings.xml
+6
-1
MemoryMessagesRepositoryTest.kt
.../java/chat/rocket/android/MemoryMessagesRepositoryTest.kt
+0
-150
gradle-wrapper.properties
gradle/wrapper/gradle-wrapper.properties
+1
-0
No files found.
app/build.gradle
View file @
6f8195b8
...
...
@@ -13,7 +13,7 @@ android {
applicationId
"chat.rocket.android"
minSdkVersion
21
targetSdkVersion
versions
.
targetSdk
versionCode
202
0
versionCode
202
1
versionName
"2.2.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled
true
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
View file @
6f8195b8
...
...
@@ -5,7 +5,21 @@ import android.view.MenuItem
import
android.view.ViewGroup
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.presentation.ChatRoomPresenter
import
chat.rocket.android.chatroom.viewmodel.*
import
chat.rocket.android.chatroom.ui.chatRoomIntent
import
chat.rocket.android.chatroom.viewmodel.AudioAttachmentViewModel
import
chat.rocket.android.chatroom.viewmodel.AuthorAttachmentViewModel
import
chat.rocket.android.chatroom.viewmodel.BaseFileAttachmentViewModel
import
chat.rocket.android.chatroom.viewmodel.BaseViewModel
import
chat.rocket.android.chatroom.viewmodel.ColorAttachmentViewModel
import
chat.rocket.android.chatroom.viewmodel.GenericFileAttachmentViewModel
import
chat.rocket.android.chatroom.viewmodel.ImageAttachmentViewModel
import
chat.rocket.android.chatroom.viewmodel.MessageAttachmentViewModel
import
chat.rocket.android.chatroom.viewmodel.MessageReplyViewModel
import
chat.rocket.android.chatroom.viewmodel.MessageViewModel
import
chat.rocket.android.chatroom.viewmodel.UrlPreviewViewModel
import
chat.rocket.android.chatroom.viewmodel.VideoAttachmentViewModel
import
chat.rocket.android.chatroom.viewmodel.toViewType
import
chat.rocket.android.main.presentation.MainNavigator
import
chat.rocket.android.util.extensions.inflate
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
chat.rocket.core.model.Message
...
...
@@ -65,6 +79,12 @@ class ChatRoomAdapter(
val
view
=
parent
.
inflate
(
R
.
layout
.
item_file_attachment
)
GenericFileAttachmentViewHolder
(
view
,
actionsListener
,
reactionListener
)
}
BaseViewModel
.
ViewType
.
MESSAGE_REPLY
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
item_message_reply
)
MessageReplyViewHolder
(
view
,
actionsListener
,
reactionListener
)
{
roomName
,
permalink
->
presenter
?.
openDirectMessage
(
roomName
,
permalink
)
}
}
else
->
{
throw
InvalidParameterException
(
"TODO - implement for ${viewType.toViewType()}"
)
}
...
...
@@ -98,15 +118,26 @@ class ChatRoomAdapter(
}
when
(
holder
)
{
is
MessageViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
MessageViewModel
)
is
ImageAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
ImageAttachmentViewModel
)
is
AudioAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
AudioAttachmentViewModel
)
is
VideoAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
VideoAttachmentViewModel
)
is
UrlPreviewViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
UrlPreviewViewModel
)
is
MessageAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
MessageAttachmentViewModel
)
is
AuthorAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
AuthorAttachmentViewModel
)
is
ColorAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
ColorAttachmentViewModel
)
is
GenericFileAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
GenericFileAttachmentViewModel
)
is
MessageViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
MessageViewModel
)
is
ImageAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
ImageAttachmentViewModel
)
is
AudioAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
AudioAttachmentViewModel
)
is
VideoAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
VideoAttachmentViewModel
)
is
UrlPreviewViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
UrlPreviewViewModel
)
is
MessageAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
MessageAttachmentViewModel
)
is
AuthorAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
AuthorAttachmentViewModel
)
is
ColorAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
ColorAttachmentViewModel
)
is
GenericFileAttachmentViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
GenericFileAttachmentViewModel
)
is
MessageReplyViewHolder
->
holder
.
bind
(
dataSet
[
position
]
as
MessageReplyViewModel
)
}
}
...
...
@@ -188,10 +219,10 @@ class ChatRoomAdapter(
message
.
apply
{
when
(
item
.
itemId
)
{
R
.
id
.
action_message_reply
->
{
presenter
?.
citeMessage
(
roomType
,
id
,
true
)
presenter
?.
citeMessage
(
room
Name
,
room
Type
,
id
,
true
)
}
R
.
id
.
action_message_quote
->
{
presenter
?.
citeMessage
(
roomType
,
id
,
false
)
presenter
?.
citeMessage
(
room
Name
,
room
Type
,
id
,
false
)
}
R
.
id
.
action_message_copy
->
{
presenter
?.
copyMessage
(
id
)
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/ImageAttachmentViewHolder.kt
View file @
6f8195b8
...
...
@@ -37,11 +37,11 @@ import timber.log.Timber
import
java.io.File
class
ImageAttachmentViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
ImageAttachmentViewModel
>(
itemView
,
listener
,
reactionListener
)
{
class
ImageAttachmentViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
ImageAttachmentViewModel
>(
itemView
,
listener
,
reactionListener
)
{
private
var
cacheKey
:
CacheKey
?
=
null
init
{
...
...
@@ -63,16 +63,19 @@ class ImageAttachmentViewHolder(itemView: View,
// TODO - implement a proper image viewer with a proper Transition
// TODO - We should definitely write our own ImageViewer
var
imageViewer
:
ImageViewer
?
=
null
val
request
=
ImageRequestBuilder
.
newBuilderWithSource
(
Uri
.
parse
(
data
.
attachmentUrl
))
.
setLowestPermittedRequestLevel
(
ImageRequest
.
RequestLevel
.
DISK_CACHE
)
.
build
()
val
request
=
ImageRequestBuilder
.
newBuilderWithSource
(
Uri
.
parse
(
data
.
attachmentUrl
))
.
setLowestPermittedRequestLevel
(
ImageRequest
.
RequestLevel
.
DISK_CACHE
)
.
build
()
cacheKey
=
DefaultCacheKeyFactory
.
getInstance
()
.
getEncodedCacheKey
(
request
,
null
)
val
pad
=
context
.
resources
.
getDimensionPixelSize
(
R
.
dimen
.
viewer_toolbar_padding
)
val
lparams
=
AppBarLayout
.
LayoutParams
(
ViewGroup
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
)
val
lparams
=
AppBarLayout
.
LayoutParams
(
ViewGroup
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
)
val
toolbar
=
Toolbar
(
context
).
also
{
it
.
inflateMenu
(
R
.
menu
.
image_actions
)
it
.
overflowIcon
?.
setTint
(
Color
.
WHITE
)
...
...
@@ -98,7 +101,7 @@ class ImageAttachmentViewHolder(itemView: View,
val
backArrowView
=
ImageView
(
context
).
also
{
it
.
setImageResource
(
R
.
drawable
.
ic_arrow_back_white_24dp
)
it
.
setOnClickListener
{
imageViewer
?.
onDismiss
()
}
it
.
setPadding
(
0
,
pad
,
pad
,
pad
)
it
.
setPadding
(
0
,
pad
,
pad
,
pad
)
}
val
layoutParams
=
AppBarLayout
.
LayoutParams
(
...
...
@@ -113,10 +116,12 @@ class ImageAttachmentViewHolder(itemView: View,
val
appBarLayout
=
AppBarLayout
(
context
).
also
{
it
.
layoutParams
=
lparams
it
.
setBackgroundColor
(
Color
.
BLACK
)
it
.
addView
(
toolbar
,
AppBarLayout
.
LayoutParams
(
AppBarLayout
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
))
it
.
addView
(
toolbar
,
AppBarLayout
.
LayoutParams
(
AppBarLayout
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
)
)
}
val
builder
=
ImageViewer
.
createPipelineDraweeControllerBuilder
()
...
...
@@ -144,12 +149,17 @@ class ImageAttachmentViewHolder(itemView: View,
val
imageFormat
=
ImageFormatChecker
.
getImageFormat
(
resource
.
openStream
())
val
imageDir
=
"${Environment.DIRECTORY_PICTURES}/Rocket.Chat Images/"
val
imagePath
=
Environment
.
getExternalStoragePublicDirectory
(
imageDir
)
val
imageFile
=
File
(
imagePath
,
"${cachedFile.nameWithoutExtension}.${imageFormat.fileExtension}"
)
val
imageFile
=
File
(
imagePath
,
"${cachedFile.nameWithoutExtension}.${imageFormat.fileExtension}"
)
imagePath
.
mkdirs
()
imageFile
.
createNewFile
()
try
{
cachedFile
.
copyTo
(
imageFile
,
true
)
MediaScannerConnection
.
scanFile
(
context
,
arrayOf
(
imageFile
.
absolutePath
),
null
)
{
path
,
uri
->
MediaScannerConnection
.
scanFile
(
context
,
arrayOf
(
imageFile
.
absolutePath
),
null
)
{
path
,
uri
->
Timber
.
i
(
"Scanned $path:"
)
Timber
.
i
(
"-> uri=$uri"
)
}
...
...
@@ -166,16 +176,21 @@ class ImageAttachmentViewHolder(itemView: View,
}
private
fun
canWriteToExternalStorage
():
Boolean
{
return
AndroidPermissionsHelper
.
checkPermission
(
itemView
.
context
,
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
return
AndroidPermissionsHelper
.
checkPermission
(
itemView
.
context
,
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
}
private
fun
checkWritingPermission
()
{
val
context
=
itemView
.
context
if
(
context
is
ContextThemeWrapper
&&
context
.
baseContext
is
Activity
)
{
val
activity
=
context
.
baseContext
as
Activity
AndroidPermissionsHelper
.
requestPermission
(
activity
,
AndroidPermissionsHelper
.
requestPermission
(
activity
,
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
,
AndroidPermissionsHelper
.
WRITE_EXTERNAL_STORAGE_CODE
)
AndroidPermissionsHelper
.
WRITE_EXTERNAL_STORAGE_CODE
)
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/adapter/MessageReplyViewHolder.kt
0 → 100644
View file @
6f8195b8
package
chat.rocket.android.chatroom.adapter
import
android.view.View
import
chat.rocket.android.chatroom.viewmodel.MessageReplyViewModel
import
chat.rocket.android.widget.emoji.EmojiReactionListener
import
kotlinx.android.synthetic.main.item_message_reply.view.*
class
MessageReplyViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
,
private
val
replyCallback
:
(
roomName
:
String
,
permalink
:
String
)
->
Unit
)
:
BaseViewHolder
<
MessageReplyViewModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
with
(
itemView
)
{
setupActionMenu
(
itemView
)
}
}
override
fun
bindViews
(
data
:
MessageReplyViewModel
)
{
with
(
itemView
)
{
button_message_reply
.
setOnClickListener
{
with
(
data
.
rawData
)
{
replyCallback
.
invoke
(
roomName
,
permalink
)
}
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/adapter/MessageViewHolder.kt
View file @
6f8195b8
...
...
@@ -37,7 +37,7 @@ class MessageViewHolder(
if
(
data
.
isTemporary
)
Color
.
GRAY
else
Color
.
BLACK
)
data
.
message
.
let
{
text_edit_indicator
.
isVisible
=
it
.
isSystemMessage
()
&&
it
.
editedBy
!=
null
text_edit_indicator
.
isVisible
=
!
it
.
isSystemMessage
()
&&
it
.
editedBy
!=
null
image_star_indicator
.
isVisible
=
it
.
starred
?.
isNotEmpty
()
?:
false
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/domain/MessageReply.kt
0 → 100644
View file @
6f8195b8
package
chat.rocket.android.chatroom.domain
data class
MessageReply
(
val
roomName
:
String
,
val
permalink
:
String
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomNavigator.kt
View file @
6f8195b8
...
...
@@ -2,6 +2,7 @@ package chat.rocket.android.chatroom.presentation
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.ui.ChatRoomActivity
import
chat.rocket.android.chatroom.ui.chatRoomIntent
import
chat.rocket.android.members.ui.newInstance
import
chat.rocket.android.server.ui.changeServerIntent
import
chat.rocket.android.util.extensions.addFragmentBackStack
...
...
@@ -15,8 +16,14 @@ class ChatRoomNavigator(internal val activity: ChatRoomActivity) {
}
fun
toPinnedMessageList
(
chatRoomId
:
String
,
chatRoomType
:
String
)
{
activity
.
addFragmentBackStack
(
"PinnedMessages"
,
R
.
id
.
fragment_container
){
chat
.
rocket
.
android
.
pinnedmessages
.
ui
.
newInstance
(
chatRoomId
,
chatRoomType
)
activity
.
addFragmentBackStack
(
"PinnedMessages"
,
R
.
id
.
fragment_container
)
{
chat
.
rocket
.
android
.
pinnedmessages
.
ui
.
newInstance
(
chatRoomId
,
chatRoomType
)
}
}
fun
toFavoriteMessageList
(
chatRoomId
:
String
,
chatRoomType
:
String
)
{
activity
.
addFragmentBackStack
(
"FavoriteMessages"
,
R
.
id
.
fragment_container
)
{
chat
.
rocket
.
android
.
favoritemessages
.
ui
.
newInstance
(
chatRoomId
,
chatRoomType
)
}
}
...
...
@@ -24,4 +31,17 @@ class ChatRoomNavigator(internal val activity: ChatRoomActivity) {
activity
.
startActivity
(
activity
.
changeServerIntent
())
activity
.
finish
()
}
fun
toDirectMessage
(
chatRoomId
:
String
,
chatRoomName
:
String
,
chatRoomType
:
String
,
isChatRoomReadOnly
:
Boolean
,
chatRoomLastSeen
:
Long
,
isChatRoomSubscribed
:
Boolean
,
isChatRoomCreator
:
Boolean
,
chatRoomMessage
:
String
)
{
activity
.
startActivity
(
activity
.
chatRoomIntent
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
isChatRoomReadOnly
,
chatRoomLastSeen
,
isChatRoomSubscribed
,
isChatRoomCreator
,
chatRoomMessage
))
activity
.
overridePendingTransition
(
R
.
anim
.
open_enter
,
R
.
anim
.
open_exit
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
6f8195b8
This diff is collapsed.
Click to expand it.
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt
View file @
6f8195b8
...
...
@@ -8,6 +8,7 @@ import chat.rocket.android.chatroom.viewmodel.suggestion.PeopleSuggestionViewMod
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.core.internal.realtime.socket.model.State
import
chat.rocket.core.model.ChatRoom
interface
ChatRoomView
:
LoadingView
,
MessageView
{
...
...
@@ -122,9 +123,9 @@ interface ChatRoomView : LoadingView, MessageView {
/**
* This user has joined the chat callback.
*
* @param
c
anPost Whether the user can post a message or not.
* @param
userC
anPost Whether the user can post a message or not.
*/
fun
onJoined
(
c
anPost
:
Boolean
)
fun
onJoined
(
userC
anPost
:
Boolean
)
fun
showReactionsPopup
(
messageId
:
String
)
...
...
@@ -135,5 +136,14 @@ interface ChatRoomView : LoadingView, MessageView {
*/
fun
populateCommandSuggestions
(
commands
:
List
<
CommandSuggestionViewModel
>)
fun
onRoomChanged
(
canPost
:
Boolean
)
/**
* Communicate whether it's a broadcast channel and if current user can post to it.
*/
fun
onRoomUpdated
(
userCanPost
:
Boolean
,
channelIsBroadcast
:
Boolean
,
userCanMod
:
Boolean
)
/**
* Open a DM with the user in the given [chatRoom] and pass the [permalink] for the message
* to reply.
*/
fun
openDirectMessage
(
chatRoom
:
ChatRoom
,
permalink
:
String
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/service/MessageService.kt
View file @
6f8195b8
...
...
@@ -60,13 +60,22 @@ class MessageService : JobService() {
)
messageRepository
.
save
(
message
.
copy
(
isTemporary
=
false
))
Timber
.
d
(
"Sent scheduled message given by id: ${message.id}"
)
}
catch
(
ex
:
RocketChat
Exception
)
{
}
catch
(
ex
:
Exception
)
{
Timber
.
e
(
ex
)
if
(
ex
.
message
?.
contains
(
"E11000"
,
true
)
==
true
)
{
// XXX: Temporary solution. We need proper error codes from the api.
messageRepository
.
save
(
message
.
copy
(
isTemporary
=
false
))
// TODO - remove the generic message when we implement :userId:/message subscription
if
(
ex
is
IllegalStateException
)
{
Timber
.
d
(
ex
,
"Probably a read-only problem..."
)
// TODO: For now we are only going to reschedule when api is fixed.
messageRepository
.
removeById
(
message
.
id
)
jobFinished
(
params
,
false
)
}
else
{
// some other error
if
(
ex
.
message
?.
contains
(
"E11000"
,
true
)
==
true
)
{
// XXX: Temporary solution. We need proper error codes from the api.
messageRepository
.
save
(
message
.
copy
(
isTemporary
=
false
))
}
jobFinished
(
params
,
true
)
}
jobFinished
(
params
,
true
)
}
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
View file @
6f8195b8
package
chat.rocket.android.chatroom.ui
import
DrawableHelper
import
android.content.Context
import
android.content.Intent
import
android.os.Bundle
...
...
@@ -28,7 +27,8 @@ fun Context.chatRoomIntent(
isChatRoomReadOnly
:
Boolean
,
chatRoomLastSeen
:
Long
,
isChatRoomSubscribed
:
Boolean
=
true
,
isChatRoomOwner
:
Boolean
=
false
isChatRoomCreator
:
Boolean
=
false
,
chatRoomMessage
:
String
?
=
null
):
Intent
{
return
Intent
(
this
,
ChatRoomActivity
::
class
.
java
).
apply
{
putExtra
(
INTENT_CHAT_ROOM_ID
,
chatRoomId
)
...
...
@@ -37,7 +37,8 @@ fun Context.chatRoomIntent(
putExtra
(
INTENT_CHAT_ROOM_IS_READ_ONLY
,
isChatRoomReadOnly
)
putExtra
(
INTENT_CHAT_ROOM_LAST_SEEN
,
chatRoomLastSeen
)
putExtra
(
INTENT_CHAT_IS_SUBSCRIBED
,
isChatRoomSubscribed
)
putExtra
(
INTENT_CHAT_ROOM_IS_OWNER
,
isChatRoomOwner
)
putExtra
(
INTENT_CHAT_ROOM_IS_CREATOR
,
isChatRoomCreator
)
putExtra
(
INTENT_CHAT_ROOM_MESSAGE
,
chatRoomMessage
)
}
}
...
...
@@ -45,24 +46,29 @@ private const val INTENT_CHAT_ROOM_ID = "chat_room_id"
private
const
val
INTENT_CHAT_ROOM_NAME
=
"chat_room_name"
private
const
val
INTENT_CHAT_ROOM_TYPE
=
"chat_room_type"
private
const
val
INTENT_CHAT_ROOM_IS_READ_ONLY
=
"chat_room_is_read_only"
private
const
val
INTENT_CHAT_ROOM_IS_
OWNER
=
"chat_room_is_owne
r"
private
const
val
INTENT_CHAT_ROOM_IS_
CREATOR
=
"chat_room_is_creato
r"
private
const
val
INTENT_CHAT_ROOM_LAST_SEEN
=
"chat_room_last_seen"
private
const
val
INTENT_CHAT_IS_SUBSCRIBED
=
"is_chat_room_subscribed"
private
const
val
INTENT_CHAT_ROOM_MESSAGE
=
"chat_room_message"
class
ChatRoomActivity
:
AppCompatActivity
(),
HasSupportFragmentInjector
{
@Inject
lateinit
var
fragmentDispatchingAndroidInjector
:
DispatchingAndroidInjector
<
Fragment
>
@Inject
lateinit
var
fragmentDispatchingAndroidInjector
:
DispatchingAndroidInjector
<
Fragment
>
// TODO - workaround for now... We will move to a single activity
@Inject
lateinit
var
serverInteractor
:
GetCurrentServerInteractor
@Inject
lateinit
var
navigator
:
ChatRoomNavigator
@Inject
lateinit
var
managerFactory
:
ConnectionManagerFactory
@Inject
lateinit
var
serverInteractor
:
GetCurrentServerInteractor
@Inject
lateinit
var
navigator
:
ChatRoomNavigator
@Inject
lateinit
var
managerFactory
:
ConnectionManagerFactory
private
lateinit
var
chatRoomId
:
String
private
lateinit
var
chatRoomName
:
String
private
lateinit
var
chatRoomType
:
String
private
var
isChatRoomReadOnly
:
Boolean
=
false
private
var
isChatRoomSubscribed
:
Boolean
=
true
private
var
isChatRoom
Owne
r
:
Boolean
=
false
private
var
isChatRoom
Creato
r
:
Boolean
=
false
private
var
chatRoomLastSeen
:
Long
=
-
1L
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
...
...
@@ -91,8 +97,10 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
isChatRoomReadOnly
=
intent
.
getBooleanExtra
(
INTENT_CHAT_ROOM_IS_READ_ONLY
,
true
)
requireNotNull
(
isChatRoomReadOnly
)
{
"no chat_room_is_read_only provided in Intent extras"
}
isChatRoomOwner
=
intent
.
getBooleanExtra
(
INTENT_CHAT_ROOM_IS_OWNER
,
false
)
requireNotNull
(
isChatRoomOwner
)
{
"no chat_room_is_owner provided in Intent extras"
}
isChatRoomCreator
=
intent
.
getBooleanExtra
(
INTENT_CHAT_ROOM_IS_CREATOR
,
false
)
requireNotNull
(
isChatRoomCreator
)
{
"no chat_room_is_creator provided in Intent extras"
}
val
chatRoomMessage
=
intent
.
getStringExtra
(
INTENT_CHAT_ROOM_MESSAGE
)
setupToolbar
()
...
...
@@ -103,7 +111,7 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
if
(
supportFragmentManager
.
findFragmentByTag
(
TAG_CHAT_ROOM_FRAGMENT
)
==
null
)
{
addFragment
(
TAG_CHAT_ROOM_FRAGMENT
,
R
.
id
.
fragment_container
)
{
newInstance
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
isChatRoomReadOnly
,
chatRoomLastSeen
,
isChatRoomSubscribed
,
isChatRoom
Owner
)
isChatRoomSubscribed
,
isChatRoom
Creator
,
chatRoomMessage
)
}
}
}
...
...
@@ -116,6 +124,17 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
return
fragmentDispatchingAndroidInjector
}
private
fun
setupToolbar
()
{
setSupportActionBar
(
toolbar
)
supportActionBar
?.
setDisplayShowTitleEnabled
(
false
)
toolbar
.
setNavigationIcon
(
R
.
drawable
.
ic_arrow_back_white_24dp
)
text_room_name
.
textContent
=
chatRoomName
showRoomTypeIcon
(
true
)
toolbar
.
setNavigationOnClickListener
{
finishActivity
()
}
}
fun
showRoomTypeIcon
(
showRoomTypeIcon
:
Boolean
)
{
if
(
showRoomTypeIcon
)
{
val
roomType
=
roomTypeOf
(
chatRoomType
)
...
...
@@ -143,17 +162,6 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
}
}
private
fun
setupToolbar
()
{
setSupportActionBar
(
toolbar
)
supportActionBar
?.
setDisplayShowTitleEnabled
(
false
)
text_room_name
.
textContent
=
chatRoomName
showRoomTypeIcon
(
true
)
toolbar
.
setNavigationOnClickListener
{
finishActivity
()
}
}
fun
setupToolbarTitle
(
toolbarTitle
:
String
)
{
text_room_name
.
textContent
=
toolbarTitle
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
6f8195b8
This diff is collapsed.
Click to expand it.
app/src/main/java/chat/rocket/android/chatroom/viewmodel/BaseViewModel.kt
View file @
6f8195b8
...
...
@@ -24,7 +24,8 @@ interface BaseViewModel<out T> {
MESSAGE_ATTACHMENT
(
6
),
AUTHOR_ATTACHMENT
(
7
),
COLOR_ATTACHMENT
(
8
),
GENERIC_FILE_ATTACHMENT
(
9
)
GENERIC_FILE_ATTACHMENT
(
9
),
MESSAGE_REPLY
(
10
)
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/MessageReplyViewModel.kt
0 → 100644
View file @
6f8195b8
package
chat.rocket.android.chatroom.viewmodel
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.domain.MessageReply
import
chat.rocket.core.model.Message
data class
MessageReplyViewModel
(
override
val
rawData
:
MessageReply
,
override
val
messageId
:
String
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?,
override
var
preview
:
Message
?,
override
var
isTemporary
:
Boolean
=
false
,
override
val
message
:
Message
)
:
BaseViewModel
<
MessageReply
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
MESSAGE_REPLY
.
viewType
override
val
layoutId
:
Int
get
()
=
R
.
layout
.
item_message_reply
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/viewmodel/RoomViewModel.kt
0 → 100644
View file @
6f8195b8
package
chat.rocket.android.chatroom.viewmodel
import
chat.rocket.core.model.ChatRoomRole
data class
RoomViewModel
(
val
roles
:
List
<
ChatRoomRole
>,
val
isBroadcast
:
Boolean
=
false
,
val
isRoom
:
Boolean
=
false
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
View file @
6f8195b8
...
...
@@ -13,16 +13,32 @@ import androidx.core.text.buildSpannedString
import
androidx.core.text.color
import
androidx.core.text.scale
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.domain.MessageReply
import
chat.rocket.android.helper.MessageHelper
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.ChatRoomsInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetSettingsInteractor
import
chat.rocket.android.server.domain.TokenRepository
import
chat.rocket.android.server.domain.baseUrl
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.isNotNullNorEmpty
import
chat.rocket.android.widget.emoji.EmojiParser
import
chat.rocket.core.model.ChatRoom
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.MessageType
import
chat.rocket.core.model.Value
import
chat.rocket.core.model.attachment.*
import
chat.rocket.core.model.attachment.Attachment
import
chat.rocket.core.model.attachment.AudioAttachment
import
chat.rocket.core.model.attachment.AuthorAttachment
import
chat.rocket.core.model.attachment.ColorAttachment
import
chat.rocket.core.model.attachment.FileAttachment
import
chat.rocket.core.model.attachment.GenericFileAttachment
import
chat.rocket.core.model.attachment.ImageAttachment
import
chat.rocket.core.model.attachment.MessageAttachment
import
chat.rocket.core.model.attachment.VideoAttachment
import
chat.rocket.core.model.isSystemMessage
import
chat.rocket.core.model.url.Url
import
kotlinx.coroutines.experimental.CommonPool
...
...
@@ -34,6 +50,8 @@ import javax.inject.Inject
class
ViewModelMapper
@Inject
constructor
(
private
val
context
:
Context
,
private
val
parser
:
MessageParser
,
private
val
roomsInteractor
:
ChatRoomsInteractor
,
private
val
messageHelper
:
MessageHelper
,
tokenRepository
:
TokenRepository
,
serverInteractor
:
GetCurrentServerInteractor
,
getSettingsInteractor
:
GetSettingsInteractor
,
...
...
@@ -47,21 +65,24 @@ class ViewModelMapper @Inject constructor(
private
val
currentUsername
:
String
?
=
localRepository
.
get
(
LocalRepository
.
CURRENT_USERNAME_KEY
)
private
val
secondaryTextColor
=
ContextCompat
.
getColor
(
context
,
R
.
color
.
colorSecondaryText
)
suspend
fun
map
(
message
:
Message
):
List
<
BaseViewModel
<*
>>
{
return
translate
(
message
)
suspend
fun
map
(
message
:
Message
,
roomViewModel
:
RoomViewModel
=
RoomViewModel
(
roles
=
emptyList
(),
isBroadcast
=
true
)):
List
<
BaseViewModel
<*
>>
{
return
translate
(
message
,
roomViewModel
)
}
suspend
fun
map
(
messages
:
List
<
Message
>):
List
<
BaseViewModel
<*
>>
=
withContext
(
CommonPool
)
{
suspend
fun
map
(
messages
:
List
<
Message
>,
roomViewModel
:
RoomViewModel
=
RoomViewModel
(
roles
=
emptyList
(),
isBroadcast
=
true
)):
List
<
BaseViewModel
<*
>>
=
withContext
(
CommonPool
)
{
val
list
=
ArrayList
<
BaseViewModel
<*>>(
messages
.
size
)
messages
.
forEach
{
list
.
addAll
(
translate
(
it
))
list
.
addAll
(
translate
(
it
,
roomViewModel
))
}
return
@withContext
list
}
private
suspend
fun
translate
(
message
:
Message
):
List
<
BaseViewModel
<*
>>
=
withContext
(
CommonPool
)
{
private
suspend
fun
translate
(
message
:
Message
,
roomViewModel
:
RoomViewModel
)
:
List
<
BaseViewModel
<*
>>
=
withContext
(
CommonPool
)
{
val
list
=
ArrayList
<
BaseViewModel
<*>>()
message
.
urls
?.
forEach
{
...
...
@@ -86,9 +107,40 @@ class ViewModelMapper @Inject constructor(
list
[
i
].
nextDownStreamMessage
=
next
}
if
(
isBroadcastReplyAvailable
(
roomViewModel
,
message
))
{
roomsInteractor
.
getById
(
currentServer
,
message
.
roomId
)
?.
let
{
chatRoom
->
val
replyViewModel
=
mapMessageReply
(
message
,
chatRoom
)
list
.
first
().
nextDownStreamMessage
=
replyViewModel
list
.
add
(
0
,
replyViewModel
)
}
}
return
@withContext
list
}
private
fun
isBroadcastReplyAvailable
(
roomViewModel
:
RoomViewModel
,
message
:
Message
):
Boolean
{
val
senderUsername
=
message
.
sender
?.
username
return
roomViewModel
.
isRoom
&&
roomViewModel
.
isBroadcast
&&
!
message
.
isSystemMessage
()
&&
senderUsername
!=
currentUsername
}
private
fun
mapMessageReply
(
message
:
Message
,
chatRoom
:
ChatRoom
):
MessageReplyViewModel
{
val
name
=
message
.
sender
?.
name
val
roomName
=
if
(
settings
.
useRealName
()
&&
name
!=
null
)
name
else
message
.
sender
?.
username
?:
""
val
permalink
=
messageHelper
.
createPermalink
(
message
,
chatRoom
)
return
MessageReplyViewModel
(
messageId
=
message
.
id
,
isTemporary
=
false
,
reactions
=
emptyList
(),
message
=
message
,
preview
=
mapMessagePreview
(
message
),
rawData
=
MessageReply
(
roomName
=
roomName
,
permalink
=
permalink
),
nextDownStreamMessage
=
null
)
}
private
fun
mapUrl
(
message
:
Message
,
url
:
Url
):
BaseViewModel
<
*
>?
{
if
(
url
.
ignoreParse
||
url
.
meta
==
null
)
return
null
...
...
@@ -313,7 +365,6 @@ class ViewModelMapper @Inject constructor(
}
private
fun
getSystemMessage
(
message
:
Message
):
CharSequence
{
println
(
message
)
val
content
=
when
(
message
.
type
)
{
//TODO: Add implementation for Welcome type.
is
MessageType
.
MessageRemoved
->
context
.
getString
(
R
.
string
.
message_removed
)
...
...
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
6f8195b8
...
...
@@ -9,7 +9,18 @@ import chat.rocket.android.helper.SharedPreferenceHelper
import
chat.rocket.android.helper.UserHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.main.presentation.MainNavigator
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.ChatRoomsInteractor
import
chat.rocket.android.server.domain.GetActiveUsersInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.JobSchedulerInteractor
import
chat.rocket.android.server.domain.PermissionsInteractor
import
chat.rocket.android.server.domain.RefreshSettingsInteractor
import
chat.rocket.android.server.domain.SaveActiveUsersInteractor
import
chat.rocket.android.server.domain.SaveChatRoomsInteractor
import
chat.rocket.android.server.domain.SettingsRepository
import
chat.rocket.android.server.domain.hasShowLastMessage
import
chat.rocket.android.server.domain.showLastMessage
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.server.infraestructure.ConnectionManager
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.chatRooms
...
...
@@ -31,9 +42,13 @@ import chat.rocket.core.internal.rest.permissions
import
chat.rocket.core.internal.rest.spotlight
import
chat.rocket.core.model.ChatRoom
import
chat.rocket.core.model.Room
import
kotlinx.coroutines.experimental.*
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.Deferred
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.async
import
kotlinx.coroutines.experimental.channels.Channel
import
kotlinx.coroutines.experimental.delay
import
kotlinx.coroutines.experimental.launch
import
timber.log.Timber
import
javax.inject.Inject
import
kotlin.reflect.KProperty1
...
...
@@ -43,7 +58,7 @@ class ChatRoomsPresenter @Inject constructor(
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
MainNavigator
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
getChatRoomsInteractor
:
Get
ChatRoomsInteractor
,
private
val
chatRoomsInteractor
:
ChatRoomsInteractor
,
private
val
saveChatRoomsInteractor
:
SaveChatRoomsInteractor
,
private
val
saveActiveUsersInteractor
:
SaveActiveUsersInteractor
,
private
val
getActiveUsersInteractor
:
GetActiveUsersInteractor
,
...
...
@@ -148,7 +163,7 @@ class ChatRoomsPresenter @Inject constructor(
val
currentServer
=
serverInteractor
.
get
()
!!
launchUI
(
strategy
)
{
try
{
val
roomList
=
getC
hatRoomsInteractor
.
getAllByName
(
currentServer
,
name
)
val
roomList
=
c
hatRoomsInteractor
.
getAllByName
(
currentServer
,
name
)
if
(
roomList
.
isEmpty
())
{
val
(
users
,
rooms
)
=
retryIO
(
"spotlight($name)"
)
{
client
.
spotlight
(
name
)
...
...
@@ -253,7 +268,7 @@ class ChatRoomsPresenter @Inject constructor(
fun
updateSortedChatRooms
()
{
launchUI
(
strategy
)
{
val
roomList
=
getC
hatRoomsInteractor
.
getAll
(
currentServer
)
val
roomList
=
c
hatRoomsInteractor
.
getAll
(
currentServer
)
view
.
updateChatRooms
(
sortRooms
(
roomList
))
}
}
...
...
@@ -453,7 +468,7 @@ class ChatRoomsPresenter @Inject constructor(
// Update a ChatRoom with a Room information
private
fun
updateRoom
(
room
:
Room
)
{
Timber
.
d
(
"Updating Room: ${room.id} - ${room.name}"
)
val
chatRooms
=
getC
hatRoomsInteractor
.
getAll
(
currentServer
).
toMutableList
()
val
chatRooms
=
c
hatRoomsInteractor
.
getAll
(
currentServer
).
toMutableList
()
val
chatRoom
=
chatRooms
.
find
{
chatRoom
->
chatRoom
.
id
==
room
.
id
}
chatRoom
?.
apply
{
val
newRoom
=
ChatRoom
(
...
...
@@ -493,7 +508,7 @@ class ChatRoomsPresenter @Inject constructor(
// Update a ChatRoom with a Subscription information
private
fun
updateSubscription
(
subscription
:
Subscription
)
{
Timber
.
d
(
"Updating subscription: ${subscription.id} - ${subscription.name}"
)
val
chatRooms
=
getC
hatRoomsInteractor
.
getAll
(
currentServer
).
toMutableList
()
val
chatRooms
=
c
hatRoomsInteractor
.
getAll
(
currentServer
).
toMutableList
()
val
chatRoom
=
chatRooms
.
find
{
chatRoom
->
chatRoom
.
id
==
subscription
.
roomId
}
chatRoom
?.
apply
{
val
newRoom
=
ChatRoom
(
...
...
@@ -532,7 +547,7 @@ class ChatRoomsPresenter @Inject constructor(
private
fun
removeRoom
(
id
:
String
,
chatRooms
:
MutableList
<
ChatRoom
>
=
getC
hatRoomsInteractor
.
getAll
(
currentServer
).
toMutableList
()
chatRooms
:
MutableList
<
ChatRoom
>
=
c
hatRoomsInteractor
.
getAll
(
currentServer
).
toMutableList
()
)
{
Timber
.
d
(
"Removing ROOM: $id"
)
synchronized
(
this
)
{
...
...
@@ -573,7 +588,7 @@ class ChatRoomsPresenter @Inject constructor(
val
username
=
user_
.
username
val
status
=
user_
.
status
if
(
username
!=
null
&&
status
!=
null
)
{
getC
hatRoomsInteractor
.
getByName
(
currentServer
,
username
)
?.
let
{
c
hatRoomsInteractor
.
getByName
(
currentServer
,
username
)
?.
let
{
val
newRoom
=
ChatRoom
(
id
=
it
.
id
,
type
=
it
.
type
,
...
...
@@ -600,10 +615,10 @@ class ChatRoomsPresenter @Inject constructor(
broadcast
=
it
.
broadcast
)
getC
hatRoomsInteractor
.
remove
(
currentServer
,
it
)
getC
hatRoomsInteractor
.
add
(
currentServer
,
newRoom
)
c
hatRoomsInteractor
.
remove
(
currentServer
,
it
)
c
hatRoomsInteractor
.
add
(
currentServer
,
newRoom
)
launchUI
(
strategy
)
{
view
.
updateChatRooms
(
sortRooms
(
getC
hatRoomsInteractor
.
getAll
(
currentServer
)))
view
.
updateChatRooms
(
sortRooms
(
c
hatRoomsInteractor
.
getAll
(
currentServer
)))
}
}
}
...
...
@@ -613,7 +628,7 @@ class ChatRoomsPresenter @Inject constructor(
Timber
.
i
(
"Updating ChatRooms"
)
launch
(
strategy
.
jobs
)
{
val
chatRoomsWithPreview
=
getChatRoomsWithPreviews
(
getC
hatRoomsInteractor
.
getAll
(
currentServer
)
c
hatRoomsInteractor
.
getAll
(
currentServer
)
)
val
chatRoomsWithStatus
=
getChatRoomWithStatus
(
chatRoomsWithPreview
)
view
.
updateChatRooms
(
chatRoomsWithStatus
)
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
6f8195b8
...
...
@@ -45,7 +45,6 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
lateinit
var
settingsRepository
:
SettingsRepository
@Inject
lateinit
var
localRepository
:
LocalRepository
private
lateinit
var
preferences
:
SharedPreferences
private
var
searchView
:
SearchView
?
=
null
private
val
handler
=
Handler
()
...
...
@@ -60,7 +59,6 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
setHasOptionsMenu
(
true
)
preferences
=
context
?.
getSharedPreferences
(
"temp"
,
Context
.
MODE_PRIVATE
)
!!
}
override
fun
onDestroy
()
{
...
...
app/src/main/java/chat/rocket/android/dagger/module/ActivityBuilder.kt
View file @
6f8195b8
...
...
@@ -10,6 +10,7 @@ import chat.rocket.android.authentication.twofactor.di.TwoFAFragmentProvider
import
chat.rocket.android.authentication.ui.AuthenticationActivity
import
chat.rocket.android.chatroom.di.ChatRoomFragmentProvider
import
chat.rocket.android.chatroom.di.ChatRoomModule
import
chat.rocket.android.chatroom.di.FavoriteMessagesFragmentProvider
import
chat.rocket.android.chatroom.di.PinnedMessagesFragmentProvider
import
chat.rocket.android.chatroom.ui.ChatRoomActivity
import
chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider
...
...
@@ -47,10 +48,15 @@ abstract class ActivityBuilder {
abstract
fun
bindMainActivity
():
MainActivity
@PerActivity
@ContributesAndroidInjector
(
modules
=
[
ChatRoomModule
::
class
,
ChatRoomFragmentProvider
::
class
,
MembersFragmentProvider
::
class
,
PinnedMessagesFragmentProvider
::
class
])
@ContributesAndroidInjector
(
modules
=
[
ChatRoomModule
::
class
,
ChatRoomFragmentProvider
::
class
,
MembersFragmentProvider
::
class
,
PinnedMessagesFragmentProvider
::
class
,
FavoriteMessagesFragmentProvider
::
class
]
)
abstract
fun
bindChatRoomActivity
():
ChatRoomActivity
@PerActivity
...
...
app/src/main/java/chat/rocket/android/favoritemessages/di/FavoriteMessagesFragmentModule.kt
0 → 100644
View file @
6f8195b8
package
chat.rocket.android.chatroom.di
import
android.arch.lifecycle.LifecycleOwner
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerFragment
import
chat.rocket.android.favoritemessages.presentation.FavoriteMessagesView
import
chat.rocket.android.favoritemessages.ui.FavoriteMessagesFragment
import
dagger.Module
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
@PerFragment
class
FavoriteMessagesFragmentModule
{
@Provides
fun
provideLifecycleOwner
(
frag
:
FavoriteMessagesFragment
):
LifecycleOwner
{
return
frag
}
@Provides
fun
provideCancelStrategy
(
owner
:
LifecycleOwner
,
jobs
:
Job
):
CancelStrategy
{
return
CancelStrategy
(
owner
,
jobs
)
}
@Provides
fun
provideFavoriteMessagesView
(
frag
:
FavoriteMessagesFragment
):
FavoriteMessagesView
{
return
frag
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/favoritemessages/di/FavoriteMessagesFragmentProvider.kt
0 → 100644
View file @
6f8195b8
package
chat.rocket.android.chatroom.di
import
chat.rocket.android.favoritemessages.ui.FavoriteMessagesFragment
import
dagger.Module
import
dagger.android.ContributesAndroidInjector
@Module
abstract
class
FavoriteMessagesFragmentProvider
{
@ContributesAndroidInjector
(
modules
=
[
FavoriteMessagesFragmentModule
::
class
])
abstract
fun
provideFavoriteMessageFragment
():
FavoriteMessagesFragment
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/favoritemessages/presentation/FavoriteMessagesPresenter.kt
0 → 100644
View file @
6f8195b8
package
chat.rocket.android.favoritemessages.presentation
import
chat.rocket.android.chatroom.viewmodel.ViewModelMapper
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.server.domain.ChatRoomsInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.internal.rest.getFavoriteMessages
import
timber.log.Timber
import
javax.inject.Inject
class
FavoriteMessagesPresenter
@Inject
constructor
(
private
val
view
:
FavoriteMessagesView
,
private
val
strategy
:
CancelStrategy
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
roomsInteractor
:
ChatRoomsInteractor
,
private
val
mapper
:
ViewModelMapper
,
factory
:
RocketChatClientFactory
)
{
private
val
client
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
var
offset
:
Int
=
0
/**
* Loads all favorite messages for room. the given room id.
*
* @param roomId The id of the room to get its favorite messages.
*/
fun
loadFavoriteMessages
(
roomId
:
String
)
{
launchUI
(
strategy
)
{
try
{
val
serverUrl
=
serverInteractor
.
get
()
!!
val
chatRoom
=
roomsInteractor
.
getById
(
serverUrl
,
roomId
)
chatRoom
?.
let
{
room
->
view
.
showLoading
()
val
favoriteMessages
=
client
.
getFavoriteMessages
(
roomId
,
room
.
type
,
offset
)
offset
=
favoriteMessages
.
offset
.
toInt
()
val
messageList
=
mapper
.
map
(
favoriteMessages
.
result
)
view
.
showFavoriteMessages
(
messageList
)
view
.
hideLoading
()
}.
ifNull
{
Timber
.
e
(
"Couldn't find a room with id: $roomId at current server."
)
}
}
catch
(
e
:
RocketChatException
)
{
Timber
.
e
(
e
)
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/favoritemessages/presentation/FavoriteMessagesView.kt
0 → 100644
View file @
6f8195b8
package
chat.rocket.android.favoritemessages.presentation
import
chat.rocket.android.chatroom.viewmodel.BaseViewModel
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.MessageView
interface
FavoriteMessagesView
:
MessageView
,
LoadingView
{
/**
* Shows the list of favorite messages for the current room.
*
* @param favoriteMessages The list of favorite messages to show.
*/
fun
showFavoriteMessages
(
favoriteMessages
:
List
<
BaseViewModel
<*
>>)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/favoritemessages/ui/FavoriteMessagesFragment.kt
0 → 100644
View file @
6f8195b8
package
chat.rocket.android.favoritemessages.ui
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v7.widget.DefaultItemAnimator
import
android.support.v7.widget.LinearLayoutManager
import
android.support.v7.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
androidx.core.view.isVisible
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import
chat.rocket.android.chatroom.ui.ChatRoomActivity
import
chat.rocket.android.chatroom.viewmodel.BaseViewModel
import
chat.rocket.android.favoritemessages.presentation.FavoriteMessagesPresenter
import
chat.rocket.android.favoritemessages.presentation.FavoriteMessagesView
import
chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import
chat.rocket.android.util.extensions.inflate
import
chat.rocket.android.util.extensions.showToast
import
chat.rocket.android.util.extensions.ui
import
dagger.android.support.AndroidSupportInjection
import
kotlinx.android.synthetic.main.fragment_favorite_messages.*
import
javax.inject.Inject
fun
newInstance
(
chatRoomId
:
String
,
chatRoomType
:
String
):
Fragment
{
return
FavoriteMessagesFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
INTENT_CHAT_ROOM_ID
,
chatRoomId
)
putString
(
INTENT_CHAT_ROOM_TYPE
,
chatRoomType
)
}
}
}
private
const
val
INTENT_CHAT_ROOM_ID
=
"chat_room_id"
private
const
val
INTENT_CHAT_ROOM_TYPE
=
"chat_room_type"
class
FavoriteMessagesFragment
:
Fragment
(),
FavoriteMessagesView
{
private
lateinit
var
chatRoomId
:
String
private
lateinit
var
chatRoomType
:
String
private
lateinit
var
adapter
:
ChatRoomAdapter
@Inject
lateinit
var
presenter
:
FavoriteMessagesPresenter
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
INTENT_CHAT_ROOM_ID
)
chatRoomType
=
bundle
.
getString
(
INTENT_CHAT_ROOM_TYPE
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?
):
View
?
=
container
?.
inflate
(
R
.
layout
.
fragment_favorite_messages
)
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
setupToolbar
()
presenter
.
loadFavoriteMessages
(
chatRoomId
)
}
override
fun
showFavoriteMessages
(
favoriteMessages
:
List
<
BaseViewModel
<*
>>)
{
ui
{
if
(
recycler_view
.
adapter
==
null
)
{
adapter
=
ChatRoomAdapter
(
chatRoomType
,
""
,
null
,
false
)
recycler_view
.
adapter
=
adapter
val
linearLayoutManager
=
LinearLayoutManager
(
context
,
LinearLayoutManager
.
VERTICAL
,
false
)
recycler_view
.
layoutManager
=
linearLayoutManager
recycler_view
.
itemAnimator
=
DefaultItemAnimator
()
if
(
favoriteMessages
.
size
>
10
)
{
recycler_view
.
addOnScrollListener
(
object
:
EndlessRecyclerViewScrollListener
(
linearLayoutManager
)
{
override
fun
onLoadMore
(
page
:
Int
,
totalItemsCount
:
Int
,
recyclerView
:
RecyclerView
?
)
{
presenter
.
loadFavoriteMessages
(
chatRoomId
)
}
})
}
no_messages_view
.
isVisible
=
favoriteMessages
.
isEmpty
()
}
adapter
.
appendData
(
favoriteMessages
)
}
}
override
fun
showMessage
(
resId
:
Int
)
{
ui
{
showToast
(
resId
)
}
}
override
fun
showMessage
(
message
:
String
)
{
ui
{
showToast
(
message
)
}
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
override
fun
showLoading
()
{
ui
{
view_loading
.
isVisible
=
true
}
}
override
fun
hideLoading
()
{
ui
{
view_loading
.
isVisible
=
false
}
}
private
fun
setupToolbar
()
{
(
activity
as
ChatRoomActivity
).
setupToolbarTitle
(
getString
(
R
.
string
.
title_favorite_messages
))
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/helper/MessageHelper.kt
0 → 100644
View file @
6f8195b8
package
chat.rocket.android.helper
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetSettingsInteractor
import
chat.rocket.android.server.domain.PublicSettings
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.common.model.RoomType
import
chat.rocket.core.model.ChatRoom
import
chat.rocket.core.model.Message
import
javax.inject.Inject
class
MessageHelper
@Inject
constructor
(
getSettingsInteractor
:
GetSettingsInteractor
,
serverInteractor
:
GetCurrentServerInteractor
)
{
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
settings
:
PublicSettings
=
getSettingsInteractor
.
get
(
currentServer
)
fun
createPermalink
(
message
:
Message
,
chatRoom
:
ChatRoom
):
String
{
val
type
=
when
(
chatRoom
.
type
)
{
is
RoomType
.
PrivateGroup
->
"group"
is
RoomType
.
Channel
->
"channel"
is
RoomType
.
DirectMessage
->
"direct"
is
RoomType
.
Livechat
->
"livechat"
else
->
"custom"
}
val
name
=
if
(
settings
.
useRealName
())
chatRoom
.
fullName
?:
chatRoom
.
name
else
chatRoom
.
name
return
"[ ]($currentServer/$type/$name?msg=${message.id}) "
}
fun
messageIdFromPermalink
(
permalink
:
String
):
String
?
{
PERMALINK_REGEX
.
find
(
permalink
.
trim
())
?.
let
{
if
(
it
.
groupValues
.
size
==
5
)
{
return
it
.
groupValues
[
MESSAGE_ID
]
}
}
return
null
}
fun
roomNameFromPermalink
(
permalink
:
String
):
String
?
{
PERMALINK_REGEX
.
find
(
permalink
.
trim
())
?.
let
{
if
(
it
.
groupValues
.
size
==
5
)
{
return
it
.
groupValues
[
ROOM_NAME
]
}
}
return
null
}
fun
roomTypeFromPermalink
(
permalink
:
String
):
String
?
{
PERMALINK_REGEX
.
find
(
permalink
.
trim
())
?.
let
{
if
(
it
.
groupValues
.
size
==
5
)
{
val
type
=
it
.
groupValues
[
ROOM_TYPE
]
return
when
(
type
)
{
"group"
->
"p"
"channel"
->
"c"
"direct"
->
"d"
"livechat"
->
"l"
else
->
type
}
}
}
return
null
}
companion
object
{
private
const
val
ROOM_TYPE
=
2
private
const
val
ROOM_NAME
=
3
private
const
val
MESSAGE_ID
=
4
val
PERMALINK_REGEX
=
"(?:__|[*#])|\\[(.+?)\\]\\(.+?//.+?/(.+)/(.+)\\?.*=(.*)\\)"
.
toRegex
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/helper/UserHelper.kt
View file @
6f8195b8
...
...
@@ -48,7 +48,7 @@ class UserHelper @Inject constructor(
/**
* Return the username for the current logged [User].
*/
fun
username
():
String
?
=
user
()
?.
username
fun
username
():
String
?
=
localRepository
.
get
(
LocalRepository
.
CURRENT_USERNAME_KEY
,
null
)
/**
* Whether current [User] is admin on the current server.
...
...
app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt
View file @
6f8195b8
package
chat.rocket.android.main.presentation
import
android.content.Context
import
chat.rocket.android.R
import
chat.rocket.android.authentication.ui.newServerIntent
import
chat.rocket.android.chatroom.ui.chatRoomIntent
...
...
@@ -37,9 +36,9 @@ class MainNavigator(internal val activity: MainActivity) {
isChatRoomReadOnly
:
Boolean
,
chatRoomLastSeen
:
Long
,
isChatRoomSubscribed
:
Boolean
,
isChatRoom
Owne
r
:
Boolean
)
{
isChatRoom
Creato
r
:
Boolean
)
{
activity
.
startActivity
(
activity
.
chatRoomIntent
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
isChatRoomReadOnly
,
chatRoomLastSeen
,
isChatRoomSubscribed
,
isChatRoom
Owne
r
))
isChatRoomReadOnly
,
chatRoomLastSeen
,
isChatRoomSubscribed
,
isChatRoom
Creato
r
))
activity
.
overridePendingTransition
(
R
.
anim
.
open_enter
,
R
.
anim
.
open_exit
)
}
...
...
app/src/main/java/chat/rocket/android/members/ui/MembersFragment.kt
View file @
6f8195b8
...
...
@@ -6,7 +6,6 @@ import android.support.v7.app.AppCompatActivity
import
android.support.v7.widget.LinearLayoutManager
import
android.support.v7.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.MenuItem
import
android.view.View
import
android.view.ViewGroup
import
chat.rocket.android.R
...
...
@@ -38,9 +37,12 @@ private const val BUNDLE_CHAT_ROOM_ID = "chat_room_id"
private
const
val
BUNDLE_CHAT_ROOM_TYPE
=
"chat_room_type"
class
MembersFragment
:
Fragment
(),
MembersView
{
@Inject
lateinit
var
presenter
:
MembersPresenter
private
val
adapter
:
MembersAdapter
=
MembersAdapter
{
memberViewModel
->
presenter
.
toMemberDetails
(
memberViewModel
)
}
private
val
linearLayoutManager
=
LinearLayoutManager
(
context
,
LinearLayoutManager
.
VERTICAL
,
false
)
@Inject
lateinit
var
presenter
:
MembersPresenter
private
val
adapter
:
MembersAdapter
=
MembersAdapter
{
memberViewModel
->
presenter
.
toMemberDetails
(
memberViewModel
)
}
private
val
linearLayoutManager
=
LinearLayoutManager
(
context
,
LinearLayoutManager
.
VERTICAL
,
false
)
private
lateinit
var
chatRoomId
:
String
private
lateinit
var
chatRoomType
:
String
...
...
@@ -58,13 +60,15 @@ class MembersFragment : Fragment(), MembersView {
}
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
container
?.
inflate
(
R
.
layout
.
fragment_members
)
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?
):
View
?
=
container
?.
inflate
(
R
.
layout
.
fragment_members
)
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
(
activity
as
AppCompatActivity
).
supportActionBar
?.
title
=
""
setupRecyclerView
()
presenter
.
loadChatRoomsMembers
(
chatRoomId
,
chatRoomType
)
}
...
...
@@ -75,8 +79,13 @@ class MembersFragment : Fragment(), MembersView {
if
(
adapter
.
itemCount
==
0
)
{
adapter
.
prependData
(
dataSet
)
if
(
dataSet
.
size
>=
59
)
{
// TODO Check why the API retorns the specified count -1
recycler_view
.
addOnScrollListener
(
object
:
EndlessRecyclerViewScrollListener
(
linearLayoutManager
)
{
override
fun
onLoadMore
(
page
:
Int
,
totalItemsCount
:
Int
,
recyclerView
:
RecyclerView
?)
{
recycler_view
.
addOnScrollListener
(
object
:
EndlessRecyclerViewScrollListener
(
linearLayoutManager
)
{
override
fun
onLoadMore
(
page
:
Int
,
totalItemsCount
:
Int
,
recyclerView
:
RecyclerView
?
)
{
presenter
.
loadChatRoomsMembers
(
chatRoomId
,
chatRoomType
,
page
*
60L
)
}
})
...
...
@@ -84,18 +93,7 @@ class MembersFragment : Fragment(), MembersView {
}
else
{
adapter
.
appendData
(
dataSet
)
}
if
(
it
is
ChatRoomActivity
)
{
it
.
showRoomTypeIcon
(
false
)
}
}
}
override
fun
onOptionsItemSelected
(
item
:
MenuItem
):
Boolean
{
if
(
item
.
itemId
==
android
.
R
.
id
.
home
)
{
(
activity
as
ChatRoomActivity
).
showRoomTypeIcon
(
true
)
return
super
.
onOptionsItemSelected
(
item
)
}
return
super
.
onOptionsItemSelected
(
item
)
}
override
fun
showLoading
()
{
...
...
@@ -129,6 +127,8 @@ class MembersFragment : Fragment(), MembersView {
}
private
fun
setupToolbar
(
totalMembers
:
Long
)
{
(
activity
as
ChatRoomActivity
?)
?.
setupToolbarTitle
(
getString
(
R
.
string
.
title_members
,
totalMembers
))
(
activity
as
ChatRoomActivity
?)
?.
setupToolbarTitle
(
getString
(
R
.
string
.
title_members
,
totalMembers
)
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/pinnedmessages/presentation/PinnedMessagesPresenter.kt
View file @
6f8195b8
...
...
@@ -2,7 +2,7 @@ package chat.rocket.android.pinnedmessages.presentation
import
chat.rocket.android.chatroom.viewmodel.ViewModelMapper
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.server.domain.
Get
ChatRoomsInteractor
import
chat.rocket.android.server.domain.ChatRoomsInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.launchUI
...
...
@@ -17,7 +17,7 @@ class PinnedMessagesPresenter @Inject constructor(
private
val
view
:
PinnedMessagesView
,
private
val
strategy
:
CancelStrategy
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
roomsInteractor
:
Get
ChatRoomsInteractor
,
private
val
roomsInteractor
:
ChatRoomsInteractor
,
private
val
mapper
:
ViewModelMapper
,
factory
:
RocketChatClientFactory
)
{
...
...
app/src/main/java/chat/rocket/android/pinnedmessages/ui/PinnedMessagesFragment.kt
View file @
6f8195b8
...
...
@@ -2,13 +2,13 @@ package chat.rocket.android.pinnedmessages.ui
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v7.app.AppCompatActivity
import
android.support.v7.widget.DefaultItemAnimator
import
android.support.v7.widget.LinearLayoutManager
import
android.support.v7.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
androidx.core.view.isVisible
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import
chat.rocket.android.chatroom.ui.ChatRoomActivity
...
...
@@ -17,14 +17,13 @@ import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import
chat.rocket.android.pinnedmessages.presentation.PinnedMessagesPresenter
import
chat.rocket.android.pinnedmessages.presentation.PinnedMessagesView
import
chat.rocket.android.util.extensions.inflate
import
chat.rocket.android.util.extensions.setVisible
import
chat.rocket.android.util.extensions.showToast
import
chat.rocket.android.util.extensions.ui
import
dagger.android.support.AndroidSupportInjection
import
kotlinx.android.synthetic.main.fragment_pinned_messages.*
import
javax.inject.Inject
fun
newInstance
(
chatRoomId
:
String
,
chatRoomType
:
String
)
:
Fragment
{
fun
newInstance
(
chatRoomId
:
String
,
chatRoomType
:
String
):
Fragment
{
return
PinnedMessagesFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
BUNDLE_CHAT_ROOM_ID
,
chatRoomId
)
...
...
@@ -49,15 +48,19 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
){
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
chatRoomType
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_TYPE
)
}
else
{
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
container
?.
inflate
(
R
.
layout
.
fragment_pinned_messages
)
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?
):
View
?
=
container
?.
inflate
(
R
.
layout
.
fragment_pinned_messages
)
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
...
...
@@ -69,21 +72,27 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
override
fun
showPinnedMessages
(
pinnedMessages
:
List
<
BaseViewModel
<*
>>)
{
ui
{
if
(
recycler_view_pinned
.
adapter
==
null
){
adapter
=
ChatRoomAdapter
(
chatRoomType
,
""
,
null
,
false
)
if
(
recycler_view_pinned
.
adapter
==
null
)
{
adapter
=
ChatRoomAdapter
(
chatRoomType
,
""
,
null
,
false
)
recycler_view_pinned
.
adapter
=
adapter
val
linearLayoutManager
=
LinearLayoutManager
(
context
,
LinearLayoutManager
.
VERTICAL
,
false
)
val
linearLayoutManager
=
LinearLayoutManager
(
context
,
LinearLayoutManager
.
VERTICAL
,
false
)
recycler_view_pinned
.
layoutManager
=
linearLayoutManager
recycler_view_pinned
.
itemAnimator
=
DefaultItemAnimator
()
if
(
pinnedMessages
.
size
>
10
){
recycler_view_pinned
.
addOnScrollListener
(
object
:
EndlessRecyclerViewScrollListener
(
linearLayoutManager
){
override
fun
onLoadMore
(
page
:
Int
,
totalItemsCount
:
Int
,
recyclerView
:
RecyclerView
?)
{
if
(
pinnedMessages
.
size
>
10
)
{
recycler_view_pinned
.
addOnScrollListener
(
object
:
EndlessRecyclerViewScrollListener
(
linearLayoutManager
)
{
override
fun
onLoadMore
(
page
:
Int
,
totalItemsCount
:
Int
,
recyclerView
:
RecyclerView
?
)
{
presenter
.
loadPinnedMessages
(
chatRoomId
)
}
})
}
togglePinView
(
pinnedMessages
.
size
)
pin_view
.
isVisible
=
pinnedMessages
.
isEmpty
(
)
}
adapter
.
appendData
(
pinnedMessages
)
}
...
...
@@ -104,22 +113,14 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
override
fun
showLoading
()
{
ui
{
view_loading
.
setVisible
(
true
)
}
ui
{
view_loading
.
isVisible
=
true
}
}
override
fun
hideLoading
()
{
ui
{
view_loading
.
setVisible
(
false
)
}
ui
{
view_loading
.
isVisible
=
false
}
}
private
fun
setupToolbar
()
{
(
activity
as
ChatRoomActivity
).
setupToolbarTitle
(
getString
(
R
.
string
.
title_pinned_messages
))
}
private
fun
togglePinView
(
size
:
Int
){
if
(
size
==
0
){
pin_view
.
setVisible
(
true
)
}
else
{
pin_view
.
setVisible
(
false
)
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/
Get
ChatRoomsInteractor.kt
→
app/src/main/java/chat/rocket/android/server/domain/ChatRoomsInteractor.kt
View file @
6f8195b8
...
...
@@ -5,7 +5,7 @@ import kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.withContext
import
javax.inject.Inject
class
Get
ChatRoomsInteractor
@Inject
constructor
(
private
val
repository
:
ChatRoomsRepository
)
{
class
ChatRoomsInteractor
@Inject
constructor
(
private
val
repository
:
ChatRoomsRepository
)
{
/**
* Get all [ChatRoom].
...
...
@@ -41,8 +41,7 @@ class GetChatRoomsInteractor @Inject constructor(private val repository: ChatRoo
* @return The [ChatRoom] object or null if we couldn't find any.
*/
suspend
fun
getById
(
serverUrl
:
String
,
roomId
:
String
):
ChatRoom
?
=
withContext
(
CommonPool
)
{
val
allChatRooms
=
repository
.
get
(
serverUrl
)
return
@withContext
allChatRooms
.
first
{
return
@withContext
repository
.
get
(
serverUrl
).
find
{
it
.
id
==
roomId
}
}
...
...
@@ -55,7 +54,7 @@ class GetChatRoomsInteractor @Inject constructor(private val repository: ChatRoo
* @return The [ChatRoom] object or null if we couldn't find any.
*/
fun
getByName
(
serverUrl
:
String
,
name
:
String
):
ChatRoom
?
{
return
getAll
(
serverUrl
).
toMutableList
().
find
{
chatRoom
->
chatRoom
.
n
ame
==
name
}
return
getAll
(
serverUrl
).
firstOrNull
{
it
.
name
==
name
||
it
.
fullN
ame
==
name
}
}
/**
...
...
app/src/main/res/drawable/ic_arrow_back_white_24dp.xml
View file @
6f8195b8
<vector
android:autoMirrored=
"true"
android:height=
"24dp"
android:tint=
"#FFFFFF"
android:viewportHeight=
"24.0"
android:viewportWidth=
"24.0"
android:width=
"24dp"
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<path
android:fillColor=
"#FF000000"
android:pathData=
"M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"
/>
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:tint=
"#FFFFFF"
android:viewportHeight=
"24.0"
android:viewportWidth=
"24.0"
>
<path
android:fillColor=
"#FF000000"
android:pathData=
"M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"
/>
</vector>
app/src/main/res/drawable/ic_hashtag_black.xml
deleted
100644 → 0
View file @
7db24109
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"13dp"
android:height=
"16dp"
android:viewportWidth=
"13.0"
android:viewportHeight=
"16.0"
>
<path
android:pathData=
"M6.626,11.495L4.505,11.495L3.714,16L1.703,16L2.495,11.495L0,11.495L0,9.604L2.824,9.604L3.374,6.484L0.824,6.484L0.824,4.571L3.714,4.571L4.516,0L6.516,0L5.714,4.571L7.846,4.571L8.648,0L10.659,0L9.857,4.571L12.264,4.571L12.264,6.484L9.516,6.484L8.967,9.604L11.429,9.604L11.429,11.495L8.637,11.495L7.846,16L5.835,16L6.626,11.495ZM4.835,9.604L6.956,9.604L7.505,6.484L5.374,6.484L4.835,9.604Z"
android:strokeColor=
"#00000000"
android:fillType=
"evenOdd"
android:fillColor=
"#000000"
android:strokeWidth=
"1"
/>
</vector>
app/src/main/res/drawable/ic_room_channel.xml
View file @
6f8195b8
...
...
@@ -6,4 +6,4 @@
<path
android:fillColor=
"#FF000000"
android:pathData=
"M22.548,9l0.452,-2h-5.364l1.364,-6h-2l-1.364,6h-5l1.364,-6h-2l-1.364,6h-6.184l-0.452,2h6.182l-1.364,6h-5.36l-0.458,2h5.364l-1.364,6h2l1.364,-6h5l-1.364,6h2l1.364,-6h6.185l0.451,-2h-6.182l1.364,-6h5.366zM13.818,15h-5l1.364,-6h5l-1.364,6z"
/>
</vector>
</vector>
\ No newline at end of file
app/src/main/res/drawable/ic_room_dm.xml
View file @
6f8195b8
...
...
@@ -6,4 +6,4 @@
<path
android:fillColor=
"#FF000000"
android:pathData=
"M13.6,13.47c-0.91,0.953 -2.191,1.545 -3.61,1.545 -2.756,0 -4.99,-2.234 -4.99,-4.99 0,-0.009 0,-0.018 0,-0.026v0.001c0,-2.761 2.239,-5 5,-5 1.131,0 2.175,0.376 3.013,1.009l-0.013,-0.009v-1h2v6.5c0,0.828 0.672,1.5 1.5,1.5s1.5,-0.672 1.5,-1.5v0,-1.5c-0.003,-4.416 -3.584,-7.994 -8,-7.994 -4.418,0 -8,3.582 -8,8s3.582,8 8,8c1.305,0 2.537,-0.312 3.625,-0.867l-0.045,0.021 0.9,1.79c-1.305,0.668 -2.847,1.06 -4.48,1.06 -5.523,0 -10,-4.477 -10,-10s4.477,-10 10,-10c5.519,0 9.994,4.472 10,9.99v0.001h-0.01v1.5c0,0.003 0,0.007 0,0.01 0,1.933 -1.567,3.5 -3.5,3.5 -1.202,0 -2.262,-0.606 -2.892,-1.528l-0.008,-0.012zM10,13c1.657,0 3,-1.343 3,-3s-1.343,-3 -3,-3v0c-1.657,0 -3,1.343 -3,3s1.343,3 3,3v0z"
/>
</vector>
</vector>
\ No newline at end of file
app/src/main/res/drawable/ic_room_lock.xml
View file @
6f8195b8
...
...
@@ -6,4 +6,4 @@
<path
android:fillColor=
"#FF000000"
android:pathData=
"M18,10v-4c0,-3.313 -2.687,-6 -6,-6s-6,2.687 -6,6v4h-3v14h18v-14h-3zM8,6c0,-2.206 1.794,-4 4,-4s4,1.794 4,4v4h-8v-4zM19,22h-14v-10h14v10z"
/>
</vector>
</vector>
\ No newline at end of file
app/src/main/res/drawable/message_reply_button_bg.xml
0 → 100644
View file @
6f8195b8
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"rectangle"
>
<solid
android:color=
"@android:color/white"
/>
<corners
android:radius=
"4dp"
/>
<stroke
android:color=
"#1D74F5"
android:width=
"2dp"
/>
</shape>
\ No newline at end of file
app/src/main/res/layout/activity_pinned_messages.xml
deleted
100644 → 0
View file @
7db24109
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:theme=
"@style/AppTheme"
tools:context=
".chatroom.ui.PinnedMessagesActivity"
>
<include
android:id=
"@+id/layout_app_bar"
layout=
"@layout/app_bar_chat_room"
/>
<FrameLayout
android:id=
"@+id/fragment_container"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_below=
"@+id/layout_app_bar"
/>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/layout/fragment_favorite_messages.xml
0 → 100644
View file @
6f8195b8
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
tools:context=
".favoritemessages.ui.FavoriteMessagesFragment"
>
<android.support.v7.widget.RecyclerView
android:id=
"@+id/recycler_view"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:scrollbars=
"vertical"
/>
<com.wang.avi.AVLoadingIndicatorView
android:id=
"@+id/view_loading"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_centerInParent=
"true"
android:visibility=
"gone"
app:indicatorColor=
"@color/black"
app:indicatorName=
"BallPulseIndicator"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
tools:visibility=
"visible"
/>
<ImageView
android:id=
"@+id/image_star"
android:layout_width=
"100dp"
android:layout_height=
"100dp"
android:src=
"@drawable/ic_action_message_star_24dp"
android:tint=
"@color/icon_grey"
app:layout_constraintBottom_toTopOf=
"@+id/text_no_favorite_messages"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintVertical_chainStyle=
"packed"
/>
<TextView
android:id=
"@+id/text_no_favorite_messages"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"24dp"
android:text=
"@string/no_favorite_messages"
android:textColor=
"@color/colorSecondaryText"
android:textSize=
"20sp"
android:textStyle=
"bold"
app:layout_constraintBottom_toTopOf=
"@+id/text_no_favorite_messages_description"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/image_star"
/>
<TextView
android:id=
"@+id/text_no_favorite_messages_description"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"16dp"
android:text=
"@string/no_favorite_description"
android:textAlignment=
"center"
android:textColor=
"@color/colorSecondaryTextLight"
android:textSize=
"16sp"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/text_no_favorite_messages"
/>
<android.support.constraint.Group
android:id=
"@+id/no_messages_view"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:visibility=
"gone"
app:constraint_referenced_ids=
"text_no_favorite_messages_description,image_star,text_no_favorite_messages"
tools:visibility=
"visible"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/fragment_pinned_messages.xml
View file @
6f8195b8
...
...
@@ -3,18 +3,14 @@
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
android:layout_height=
"match_parent"
tools:context=
".pinnedmessages.ui.PinnedMessagesFragment"
>
<android.support.v7.widget.RecyclerView
android:id=
"@+id/recycler_view_pinned"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintHorizontal_bias=
"0.0"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintVertical_bias=
"1.0"
/>
android:scrollbars=
"vertical"
/>
<com.wang.avi.AVLoadingIndicatorView
android:id=
"@+id/view_loading"
...
...
@@ -38,46 +34,46 @@
android:layout_height=
"100dp"
android:src=
"@drawable/ic_action_message_pin_24dp"
android:tint=
"@color/icon_grey"
app:layout_constraint
Start_toStartOf=
"parent
"
app:layout_constraint
Bottom_toTopOf=
"@id/tv_pin_title
"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toTopOf=
"@id/tv_pin_title"
app:layout_constraintVertical_chainStyle=
"packed"
/>
<TextView
android:id=
"@+id/tv_pin_title"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"24dp"
android:text=
"@string/no_pinned_messages"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@id/iv_pin_icon"
app:layout_constraintBottom_toTopOf=
"@id/tv_pin_description"
android:textColor=
"@color/colorSecondaryText"
android:textSize=
"20sp"
android:layout_marginTop=
"24dp"
android:textStyle=
"bold"
android:textColor=
"@color/colorSecondaryText"
/>
app:layout_constraintBottom_toTopOf=
"@id/tv_pin_description"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@id/iv_pin_icon"
/>
<TextView
android:id=
"@+id/tv_pin_description"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"@string/no_pinned_description"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@id/tv_pin_title"
app:layout_constraintBottom_toBottomOf=
"parent"
android:layout_marginTop=
"16dp"
android:text=
"@string/no_pinned_description"
android:textAlignment=
"center"
android:textColor=
"@color/colorSecondaryTextLight"
android:textSize=
"16sp"
android:textColor=
"@color/colorSecondaryTextLight"
/>
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@id/tv_pin_title"
/>
<android.support.constraint.Group
android:id=
"@+id/pin_view"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
app:constraint_referenced_ids=
"tv_pin_description,iv_pin_icon,tv_pin_title"
android:visibility=
"gone"
app:constraint_referenced_ids=
"tv_pin_description,iv_pin_icon,tv_pin_title"
tools:visibility=
"visible"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/item_message_reply.xml
0 → 100644
View file @
6f8195b8
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:id=
"@+id/message_container"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"?android:attr/selectableItemBackground"
android:clickable=
"true"
android:focusable=
"true"
android:paddingBottom=
"@dimen/message_item_top_and_bottom_padding"
android:paddingEnd=
"@dimen/screen_edge_left_and_right_padding"
android:paddingStart=
"@dimen/screen_edge_left_and_right_padding"
android:paddingTop=
"@dimen/message_item_top_and_bottom_padding"
>
<Button
android:id=
"@+id/button_message_reply"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"2dp"
android:layout_marginTop=
"5dp"
android:layout_marginStart=
"56dp"
android:background=
"@drawable/message_reply_button_bg"
android:text=
"@string/action_msg_reply"
android:textAllCaps=
"false"
android:textColor=
"#1D74F5"
android:textSize=
"14sp"
app:layout_constraintLeft_toLeftOf=
"parent"
/>
<include
layout=
"@layout/layout_reactions"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
app:layout_constraintEnd_toEndOf=
"@+id/button_message_reply"
app:layout_constraintStart_toStartOf=
"@+id/button_message_reply"
app:layout_constraintTop_toBottomOf=
"@+id/button_message_reply"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/menu/chatroom_actions.xml
View file @
6f8195b8
...
...
@@ -11,4 +11,9 @@
android:id=
"@+id/action_pinned_messages"
android:title=
"@string/title_pinned_messages"
app:showAsAction=
"never"
/>
<item
android:id=
"@+id/action_favorite_messages"
android:title=
"@string/title_favorite_messages"
app:showAsAction=
"never"
/>
</menu>
\ No newline at end of file
app/src/main/res/values-es/strings.xml
View file @
6f8195b8
...
...
@@ -166,7 +166,13 @@
<!-- Pinned Messages -->
<string
name=
"title_pinned_messages"
>
Mensajes fijados
</string>
<string
name=
"no_pinned_messages"
>
Sin mensajes fijadas
</string>
<string
name=
"no_pinned_description"
>
Todas las mensajes fijadas\naparecen aquí.
</string>
<string
name=
"no_pinned_description"
>
Todas las mensajes fijadas\naparecen aquí
</string>
<!-- Favorite Messages -->
<!-- TODO Add proper translation-->
<string
name=
"title_favorite_messages"
>
Favorite Messages
</string>
<string
name=
"no_favorite_messages"
>
No favorite messages
</string>
<string
name=
"no_favorite_description"
>
All the favorite messages\nappear here
</string>
<!-- Upload Messages -->
<string
name=
"max_file_size_exceeded"
>
Tamaño del archivo (%1$d bytes) excedió el tamaño máximo de carga de %2$d bytes
</string>
...
...
app/src/main/res/values-fr/strings.xml
View file @
6f8195b8
...
...
@@ -167,7 +167,13 @@
<!-- Pinned Messages -->
<string
name=
"title_pinned_messages"
>
Messages épinglés
</string>
<string
name=
"no_pinned_messages"
>
Aucun message épinglé
</string>
<string
name=
"no_pinned_description"
>
Tous les messages épinglés\napparaissent ici.
</string>
<string
name=
"no_pinned_description"
>
Tous les messages épinglés\napparaissent ici
</string>
<!-- Favorite Messages -->
<!-- TODO Add proper translation-->
<string
name=
"title_favorite_messages"
>
Favorite Messages
</string>
<string
name=
"no_favorite_messages"
>
No favorite messages
</string>
<string
name=
"no_favorite_description"
>
All the favorite messages\nappear here
</string>
<!-- Upload Messages -->
<string
name=
"max_file_size_exceeded"
>
Taille du fichier (%1$d bytes) dépassé la taille de téléchargement maximale de %2$d bytes
</string>
...
...
app/src/main/res/values-hi-rIN/strings.xml
View file @
6f8195b8
...
...
@@ -170,6 +170,12 @@
<string
name=
"no_pinned_messages"
>
कोई पिन संदेश नहीं
</string>
<string
name=
"no_pinned_description"
>
सभी पिन किए गए संदेश यहां\nदिखाई देते हैं।
</string>
<!-- Favorite Messages -->
<!-- TODO Add proper translation-->
<string
name=
"title_favorite_messages"
>
Favorite Messages
</string>
<string
name=
"no_favorite_messages"
>
No favorite messages
</string>
<string
name=
"no_favorite_description"
>
All the favorite messages\nappear here
</string>
<!-- Upload Messages -->
<string
name=
"max_file_size_exceeded"
>
फ़ाइल का आकार %1$d बाइट्स ने %2$d बाइट्स के अधिकतम अपलोड आकार को पार कर लिया है
</string>
...
...
app/src/main/res/values-pt-rBR/strings.xml
View file @
6f8195b8
...
...
@@ -158,6 +158,12 @@
<string
name=
"no_pinned_messages"
>
Nenhuma mensagem pinada
</string>
<string
name=
"no_pinned_description"
>
Todas as mensagens pinadas\naparecerão aqui
</string>
<!-- Favorite Messages -->
<!-- TODO Add proper translation-->
<string
name=
"title_favorite_messages"
>
Messagens Favoritas
</string>
<string
name=
"no_favorite_messages"
>
Nenhuma messagem favorita
</string>
<string
name=
"no_favorite_description"
>
Todas as mensagens favoritas\naparecerão aqui
</string>
<!-- Upload Messages -->
<string
name=
"max_file_size_exceeded"
>
Tamanho de arquivo (%1$d bytes) excedeu tamanho máximo de upload (%2$d bytes)
</string>
...
...
app/src/main/res/values-uk-rUA/strings.xml
deleted
100644 → 0
View file @
7db24109
This diff is collapsed.
Click to expand it.
app/src/main/res/values/strings.xml
View file @
6f8195b8
...
...
@@ -155,7 +155,12 @@
<!-- Pinned Messages -->
<string
name=
"title_pinned_messages"
>
Pinned Messages
</string>
<string
name=
"no_pinned_messages"
>
No pinned messages
</string>
<string
name=
"no_pinned_description"
>
All the pinned messages\nappear here.
</string>
<string
name=
"no_pinned_description"
>
All the pinned messages\nappear here
</string>
<!-- Favorite Messages -->
<string
name=
"title_favorite_messages"
>
Favorite Messages
</string>
<string
name=
"no_favorite_messages"
>
No favorite messages
</string>
<string
name=
"no_favorite_description"
>
All the favorite messages\nappear here
</string>
<!-- Upload Messages -->
<string
name=
"max_file_size_exceeded"
>
File size %1$d bytes exceeded max upload size of %2$d bytes
</string>
...
...
app/src/test/java/chat/rocket/android/MemoryMessagesRepositoryTest.kt
deleted
100644 → 0
View file @
7db24109
package
chat.rocket.android
import
chat.rocket.android.server.infraestructure.MemoryMessagesRepository
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.MessageType
import
kotlinx.coroutines.experimental.runBlocking
import
org.hamcrest.CoreMatchers.notNullValue
import
org.hamcrest.MatcherAssert.assertThat
import
org.junit.Before
import
org.junit.Test
import
org.hamcrest.CoreMatchers.`is`
as
isEqualTo
class
MemoryMessagesRepositoryTest
{
val
repository
=
MemoryMessagesRepository
()
val
msg
=
Message
(
id
=
"messageId"
,
roomId
=
"GENERAL"
,
message
=
"Beam me up, Scotty."
,
timestamp
=
1511443964815
,
attachments
=
null
,
sender
=
null
,
avatar
=
null
,
channels
=
null
,
editedAt
=
null
,
editedBy
=
null
,
groupable
=
true
,
mentions
=
null
,
parseUrls
=
false
,
senderAlias
=
null
,
type
=
MessageType
.
MessageRemoved
(),
updatedAt
=
1511443964815
,
urls
=
null
,
pinned
=
false
,
reactions
=
null
)
val
msg2
=
Message
(
id
=
"messageId2"
,
roomId
=
"sandbox"
,
message
=
"Highly Illogical"
,
timestamp
=
1511443964818
,
attachments
=
null
,
sender
=
null
,
avatar
=
null
,
channels
=
null
,
editedAt
=
null
,
editedBy
=
null
,
groupable
=
true
,
mentions
=
null
,
parseUrls
=
false
,
senderAlias
=
null
,
type
=
MessageType
.
MessageRemoved
(),
updatedAt
=
1511443964818
,
urls
=
null
,
pinned
=
false
,
reactions
=
null
)
@Before
fun
setup
()
{
runBlocking
{
repository
.
clear
()
}
}
@Test
fun
`
save
()
should
save
a
single
message
`
()
{
runBlocking
{
assertThat
(
repository
.
getAll
().
size
,
isEqualTo
(
0
))
repository
.
save
(
msg
)
val
allMessages
=
repository
.
getAll
()
assertThat
(
allMessages
.
size
,
isEqualTo
(
1
))
allMessages
[
0
].
apply
{
assertThat
(
id
,
isEqualTo
(
"messageId"
))
assertThat
(
message
,
isEqualTo
(
"Beam me up, Scotty."
))
assertThat
(
roomId
,
isEqualTo
(
"GENERAL"
))
}
}
}
@Test
fun
`
saveAll
()
should
all
saved
messages
`
()
{
runBlocking
{
assertThat
(
repository
.
getAll
().
size
,
isEqualTo
(
0
))
repository
.
saveAll
(
listOf
(
msg
,
msg2
))
val
allMessages
=
repository
.
getAll
()
assertThat
(
allMessages
.
size
,
isEqualTo
(
2
))
allMessages
[
0
].
apply
{
assertThat
(
id
,
isEqualTo
(
"messageId"
))
assertThat
(
message
,
isEqualTo
(
"Beam me up, Scotty."
))
assertThat
(
roomId
,
isEqualTo
(
"GENERAL"
))
}
allMessages
[
1
].
apply
{
assertThat
(
id
,
isEqualTo
(
"messageId2"
))
assertThat
(
message
,
isEqualTo
(
"Highly Illogical"
))
assertThat
(
roomId
,
isEqualTo
(
"sandbox"
))
}
}
}
@Test
fun
`
getById
()
should
return
a
single
message
`
()
{
runBlocking
{
repository
.
saveAll
(
listOf
(
msg
,
msg2
))
var
singleMsg
=
repository
.
getById
(
"messageId"
)
assertThat
(
singleMsg
,
notNullValue
())
singleMsg
!!
.
apply
{
assertThat
(
id
,
isEqualTo
(
"messageId"
))
assertThat
(
message
,
isEqualTo
(
"Beam me up, Scotty."
))
assertThat
(
roomId
,
isEqualTo
(
"GENERAL"
))
}
singleMsg
=
repository
.
getById
(
"messageId2"
)
assertThat
(
singleMsg
,
notNullValue
())
singleMsg
!!
.
apply
{
assertThat
(
id
,
isEqualTo
(
"messageId2"
))
assertThat
(
message
,
isEqualTo
(
"Highly Illogical"
))
assertThat
(
roomId
,
isEqualTo
(
"sandbox"
))
}
}
}
@Test
fun
`
getByRoomId
()
should
return
all
messages
for
room
id
or
an
empty
list
`
()
{
runBlocking
{
repository
.
saveAll
(
listOf
(
msg
,
msg2
))
var
roomMessages
=
repository
.
getByRoomId
(
"faAad32fkasods2"
)
assertThat
(
roomMessages
.
isEmpty
(),
isEqualTo
(
true
))
roomMessages
=
repository
.
getByRoomId
(
"sandbox"
)
assertThat
(
roomMessages
.
size
,
isEqualTo
(
1
))
roomMessages
[
0
].
apply
{
assertThat
(
id
,
isEqualTo
(
"messageId2"
))
assertThat
(
message
,
isEqualTo
(
"Highly Illogical"
))
assertThat
(
roomId
,
isEqualTo
(
"sandbox"
))
}
roomMessages
=
repository
.
getByRoomId
(
"GENERAL"
)
assertThat
(
roomMessages
.
size
,
isEqualTo
(
1
))
roomMessages
[
0
].
apply
{
assertThat
(
id
,
isEqualTo
(
"messageId"
))
assertThat
(
message
,
isEqualTo
(
"Beam me up, Scotty."
))
assertThat
(
roomId
,
isEqualTo
(
"GENERAL"
))
}
}
}
}
\ No newline at end of file
gradle/wrapper/gradle-wrapper.properties
View file @
6f8195b8
...
...
@@ -4,3 +4,4 @@ distributionPath=wrapper/dists
zipStoreBase
=
GRADLE_USER_HOME
zipStorePath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-4.6-all.zip
distributionSha256Sum
=
9af7345c199f1731c187c96d3fe3d31f5405192a42046bafa71d846c3d9adacb
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